(Vue)阻止冒泡事件之下拉菜单的实现

这是本人作为程序媛的第一篇博客,如有出现纰漏的地方,请各位大佬不吝赐教!!!

1、(Vue)事件冒泡

所谓的事件冒泡,即事件由子元素传递给父元素的过程称之为事件的冒泡
如:在两个div中,外层div嵌套着一个子div,并相应的给父(div)与子(div)分别添加click事件。当触发子(div)的click事件时,父级的click事件也会相应的触发。这易导致页面展现效果出现错乱。
在此,我以下拉菜单的实例进行阐述所遇到的事件冒泡问题,以及该如何去进行解决事件的冒泡!
实现效果图:

(Vue)阻止冒泡事件之下拉菜单的实现_第1张图片

(Vue)阻止冒泡事件之下拉菜单的实现_第2张图片
(Vue)阻止冒泡事件之下拉菜单的实现_第3张图片

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>

你可能感兴趣的:(Vue冒泡,vue,html,js)