首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Vue stopPropagation不工作-从子到父

Vue stopPropagation不工作-从子到父
EN

Stack Overflow用户
提问于 2018-09-03 18:47:53
回答 1查看 9.7K关注 0票数 5

我在为事件的传播而挣扎。如果没有保存数据,则任务是防止单击任何内容。因此,左边的div包含一个选项树。单击项目后,将显示右div中的设置。我想警告用户,当他试图点击外部设置div时,数据没有保存。

代码如下所示:

代码语言:javascript
运行
复制
   <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包用于检测外部div的单击。效果很好。问题是,这段代码没有做任何事情:

代码语言:javascript
运行
复制
        checkIfSaved : function (event, el)
        {
            event.stopPropagation();
            event.preventDefault();
        },

无论如何,单击都会传播到父节点。如果我将事件@click放置到父程序中,则会触发所有单击。

是否只停止从父母到子女的传播?

EN

Stack Overflow用户

回答已采纳

发布于 2018-09-04 06:31:03

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

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

代码语言:javascript
运行
复制
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.`);
    },
  },
});
代码语言:javascript
运行
复制
.box { padding: 20px; }
.red { background-color: red; }
.yellow { background-color: yellow; }
.blue { background-color: blue; }
代码语言:javascript
运行
复制
<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>

  1. 单击蓝色框。蓝色框首先接收单击事件,然后像预期的那样气泡到黄色然后是红色框。
  2. 单击黄色框。黄色然后红色的框接收单击事件,然后一旦它气泡到document元素( click-outside指令已经将事件侦听器附加到文档元素),就调用click-outside处理程序。此时调用stopPropagation()没有任何作用,因为事件已经冒泡到顶部。

我不认为.stop修饰符会在您的示例中做任何事情,因为v-click-outside不支持这个修饰符(.stop只支持v-onv-click-outside需要支持它)。

因此,为了解决您的问题,您需要更改事件的顺序:v-click-outside需要在@click之前首先处理。

可以通过使用事件捕获来更改v-click-outside实现来实现这一点,如下所示:

代码语言:javascript
运行
复制
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.`);
    },
  },
});
代码语言:javascript
运行
复制
.box { padding: 20px; }
.red { background-color: red; }
.yellow { background-color: yellow; }
.blue { background-color: blue; }
代码语言:javascript
运行
复制
<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-外部事件提交一个pull请求来支持这个特性呢?

票数 5
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52154917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档