这是本人作为程序媛的第一篇博客,如有出现纰漏的地方,请各位大佬不吝赐教!!!
1、(Vue)事件冒泡
所谓的事件冒泡,即事件由子元素传递给父元素的过程称之为事件的冒泡。
如:在两个div中,外层div嵌套着一个子div,并相应的给父(div)与子(div)分别添加click事件。当触发子(div)的click事件时,父级的click事件也会相应的触发。这易导致页面展现效果出现错乱。
在此,我以下拉菜单的实例进行阐述所遇到的事件冒泡问题,以及该如何去进行解决事件的冒泡!
实现效果图:
1.1(Vue)事件冒泡实例
在该实例中,父级div点击事件为:“showMenuListUl()”,子级中的点击事件为li中的"clickPayMethod(item.id)"。当点击菜单栏时进行下拉菜单的展示,当选中下拉菜单的子选项时,对下拉菜单进行相应的隐藏。但由于事件的冒泡,对下拉菜单的子选项进行完相应的选择之后,无法对下拉菜单进行相应的隐藏。
<div class="selectBody" @click="showMenuListUl">
<span><img :src="showMenuList[index].imgpath" alt="logo" /></span>
<span><input type="button" v-model="inputtext" /></span>
<span>
<img v-show="showdown" src="@/assets/down.svg" alt="down">
<img v-show="!showdown" src="@/assets/up.svg" alt="up">
</span>
<div class="selectBodyUl" v-show="showSelectBodyUl">
<ul>
<li v-for="item in showMenuList"
:key="item.index"
@click="clickPayMethod(item.id)"
:class="item.id == selected ? 'selected' : ''">
<span><img :src="item.imgpath"></span>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</div>
1.2(Vue)事件冒泡实例的解决
解决方案: 为子级的click事件添加“.stop”,如下代码所示,将li中的@click="clickPayMethod(item.id)"更改为@click.stop=“clickPayMethod(item.id)”
<div class="selectBody" @click="showMenuListUl">
<span><img :src="showMenuList[index].imgpath" alt="logo" /></span>
<span><input type="button" v-model="inputtext" /></span>
<span>
<img v-show="showdown" src="@/assets/down.svg" alt="down">
<img v-show="!showdown" src="@/assets/up.svg" alt="up">
</span>
<div class="selectBodyUl" v-show="showSelectBodyUl">
<ul>
<li v-for="item in showMenuList"
:key="item.index"
@click.stop="clickPayMethod(item.id)"
:class="item.id == selected ? 'selected' : ''">
<span><img :src="item.imgpath"></span>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</div>
2、(Vue)下拉菜单实现过程完整代码
<template>
<div class="selectMenu">
<div class="selectMenuContainer">
<h1>Vue下拉菜单功能的实现</h1>
<div class="selectBody" @click="showMenuListUl">
<span><img :src="showMenuList[index].imgpath" alt="logo" /></span>
<span><input type="button" v-model="inputtext" /></span>
<span>
<img v-show="showdown" src="@/assets/down.svg" alt="down">
<img v-show="!showdown" src="@/assets/up.svg" alt="up">
</span>
<div class="selectBodyUl" v-show="showSelectBodyUl">
<ul>
<li v-for="item in showMenuList"
:key="item.index"
@click.stop="clickPayMethod(item.id)"
:class="item.id == selected ? 'selected' : ''">
<span><img :src="item.imgpath"></span>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
```html
<script>
export default {
name: 'test',
data () {
return {
inputtext: '',
itemimg: '',
index: 0,
showdown: true,
selected: 0,
showSelectBodyUl: false,
showMenuList: [{
id: 0,
name: '微信',
imgpath: require('@/assets/wechat.svg')
}, {
id: 1,
name: '银行卡',
imgpath: require('@/assets/bank.svg')
}, {
id: 2,
name: '支付宝',
imgpath: require('@/assets/paypal.svg')
}]
}
},
methods: {
clickPayMethod (id1) {
this.index = id1
this.inputtext = this.showMenuList[id1].name
this.selected = id1
this.showSelectBodyUl = false
this.showdown = true
},
showMenuListUl () {
this.showSelectBodyUl = !this.showSelectBodyUl
this.showdown = false
}
},
created() {
this.inputtext = this.showMenuList[0].name
}
}
</script>
<style lang="less" scoped>
.selectMenu {
margin: 0;
padding: 0;
.selectMenuContainer {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.selectBody {
display: flex;
justify-content: center;
align-items: center;
padding: 5px;
border: 1px solid oldlace;
border-radius: 2px;
box-shadow: 1px 1px 0px 1px #f3f3f3;
position: relative;
cursor: pointer;
img {
width: 24px;
height: 24px;
align-items: center;
}
input {
border: none;
background: none;
width: 150px;
outline: none;
cursor: pointer;
}
}
.selectBodyUl {
width: 205px;
margin-top: 10px;
text-align: left;
border: 1px solid oldlace;
border-radius: 2px;
box-shadow: 1px 1px 0px 1px #f3f3f3;
position: absolute;
right: 0;
top: 35px;
ul {
list-style-type: none;
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
padding: 0;
li {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 30px;
&:not(:last-child) {
margin-bottom: 5px;
}
span {
display: flex;
align-items: center;
}
}
li:hover {
background: cornsilk;
}
.selected {
background: cornsilk;
}
img {
width: 24px;
height: 24px;
margin-right: 5px;
}
}
}
}
}
</style>