javascript - Vue stopPropagation 不起作用 - child 到 parent

标签 javascript vue.js event-handling dom-events vue-events

我正在为事件传播而苦苦挣扎。如果未保存数据,任务是防止单击任何其他内容。所以,左边的 div 包含一个选项树。单击项目后,将显示右侧 div 中的设置。我想警告用户,当他尝试在设置 div 之外单击时,数据未保存。

代码如下所示:

   <div class="row">
       <div class="col-sm-6">
           <tree
               :data="treeData">
               .. some tree data
           </tree>
       </div>
       <div class="col-sm-6">
               <div class="treeOptionEdit" v-if="showEditBox" v-click-outside.stop="checkIfSaved">

           ... setting input fields
vue-outside-events package 用于检测 div 之外的点击。它工作正常。问题是,这段代码没有做任何事情:
        checkIfSaved : function (event, el)
        {
            event.stopPropagation();
            event.preventDefault();
        },

无论如何,点击都会传播到父级。如果我把一个事件 @click对 parent 来说,它会被触发所有点击。

停止传播是否仅在 parent 之间有效?

最佳答案

我不熟悉 v-click-outside实现,但是“点击外部”事件通常是通过在文档/正文元素上使用事件委托(delegate)来实现的,因此到那时该事件已经传播并且无法停止。

这是正在发生的事情的一个小例子:

Vue.directive('click-outside', {
  bind(el, { value }) {
    el._handler = e => {
      if (!el.contains(e.target)) {
        value(e);
      }
    };
    
    document.addEventListener('click', el._handler);
  },
  
  unbind(el) {
    document.removeEventListener('click', el._handler);
  },
});

new Vue({
  el: '#app',
  methods: {
    onClick(e, color) {
      alert(`Clicked the ${color} box.`);
    },
    
    onClickOutside(e, color) {
      e.stopPropagation();
      alert(`Clicked outside of ${color} box.`);
    },
  },
});
.box { padding: 20px; }
.red { background-color: red; }
.yellow { background-color: yellow; }
.blue { background-color: blue; }
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>

<div id="app">
  <div class="box red" @click="onClick($event, 'red')">
    <div class="box yellow" @click="onClick($event, 'yellow')">
      <div class="box blue" @click="onClick($event, 'blue')" v-click-outside="e => onClickOutside(e, 'blue')">
      </div>
    </div>
  </div>
</div>


  • 单击蓝色框。蓝色框首先接收到点击事件,然后它会像预期的那样冒泡到黄色然后是红色框。
  • 点击黄色框。黄色和红色的框接收点击事件,然后一旦它冒泡到文档元素(click-outside 指令已将事件监听器附加到其中)click-outside处理程序被调用。调用stopPropagation()此刻什么都不做,因为事件已经冒泡到顶部。

  • 我不相信 .stop修饰符在您的示例中执行任何操作,因为 v-click-outside不支持此修饰符(.stop 仅受 v-on 支持;v-click-outside 需要支持它)。

    因此,要解决您的问题,您需要更改事件的顺序:v-click-outside需要先处理@click .

    您可以通过更改 v-click-outside 来实现此目的。使用事件捕获实现如下:

    Vue.directive('click-outside', {
      bind(el, { value }) {
        el._handler = e => {
          if (!el.contains(e.target)) {
            value(e);
          }
        };
        
        // *** Using capturing ***
        document.addEventListener('click', el._handler, { capture: true });
      },
      
      unbind(el) {
        document.removeEventListener('click', el._handler, { capture: true });
      },
    });
    
    new Vue({
      el: '#app',
      methods: {
        onClick(e, color) {
          alert(`Clicked the ${color} box.`);
        },
        
        onClickOutside(e, color) {
          e.stopPropagation();
          alert(`Clicked outside of ${color} box.`);
        },
      },
    });
    .box { padding: 20px; }
    .red { background-color: red; }
    .yellow { background-color: yellow; }
    .blue { background-color: blue; }
    <script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
    
    <div id="app">
      <div class="box red" @click="onClick($event, 'red')">
        <div class="box yellow" @click="onClick($event, 'yellow')">
          <div class="box blue" @click="onClick($event, 'blue')" v-click-outside="e => onClickOutside(e, 'blue')">
          </div>
        </div>
      </div>
    </div>


    为什么不向 vue-outside-events 提交拉取请求?支持这个功能?

    关于javascript - Vue stopPropagation 不起作用 - child 到 parent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52154917/

    相关文章:

    javascript - 如何直接从组件访问 Vue 的路由数组?

    javascript - 在 Prototype 中绑定(bind)和触发 native 和自定义事件

    javascript - 如何将 eventListener 添加到 JavaScript 中的对象,该对象将在操作对象时触发?

    javascript - 比较 3 个 JavaScript 变量

    javascript - 请解释为什么它 "doesn' t 甚至改变数字的值是有意义的”

    javascript - 组织结构图指令中的数据迭代

    javascript - 显示除 2 个特定项目之外的对象项目

    vue.js - vue 和 vue-material : how to start?

    javascript - Vue.js:如何在我从 firebase 存储中检索数据后异步加载模板?

    java - 在 Android 中处理事件的最佳方式