最近在使用Element组件的时候,遇到了列表内图片点击预览触发列的点击事件问题;其实就是事件的冒泡和捕捉,就整理了一下vue内的事件修饰符,为记录也为避个坑。
1、native
子组件:
<div style="border: 1px solid rgb(24, 19, 19); height: 100px;width: 100px;">
<button @click="onChildClick">ChildClick</button>
</div>
父组件
<Child @click="onChildClick"></Child>
如果我们直接在Child上定义事件,在vue2是无法触发的。这个时候就需要加上native,这个是因为对于子组件中未被定义的事件,是通过this.$emit才能触发的,所以要想实现这个效果需要将原生 DOM 监听器添加到子组件的根元素中。
父组件
<Child @click.native="onChildClick"></Child>
当然vue3已经去掉了.native修饰符。新增的 emits 选项允许子组件定义真正会被触发的事件。
因此,对于子组件中未被定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false)。
2、vue2提供的常见修饰符如下:
stop once self capture prevent
stop: 阻止事件冒泡
<ul @click="onUlClick">
<li @click="onLiClick">one</li>
<li @click="onLiClick">two</li>
</ul>
// 如果我们点击li事件,也会触发ul的事件,这个就是冒泡引起的。
<ul @click="onUlClick">
<li @click.stop="onLiClick">one</li>
<li @click="onLiClick">two</li>
</ul>
// 如果我们加上.stop修饰符,就会阻止冒泡不会触发ul的事件。
once: 事件只执行一次
<ul @click="onUlClick">
<li @click.once="onLiClick">one</li>
<li @click="onLiClick">two</li>
</ul>
// 如果我们点击li事件,它只会触发一下,但是再次点击也会触发ul的事件。
self: 只有点击自身事件才会触发,同时阻止子元素的事件冒泡
<ul @click.self="onUlClick">
<li @click="onLiClick">one</li>
<li @click="onLiClick">two</li>
</ul>
// 这样只有点击ul自身的时候才会触发事件,还能阻止li的事件冒泡。
capture:可以将事件处理改为捕获模式,即从外部元素向内部元素传播。
<ul @click.capture="onUlClick">
<li>one</li>
<li>two</li>
</ul>
// 这样点击li也会触发事件。
prevent: 阻止默认事件
<a href='http:xx.com' @click='navigate'></a>
// 如果我们想在跳转之前做一些处理,这样是无法阻止的。
<a href='http://www.baidu.com' @click.prevent='navigate'>go</a>
// 这样就能阻止默认行为,触发我们定义的事件去处理逻辑。
js 原生阻止冒泡和默认行为:
w3c是e.stopPropagation(),IE则是使用window.event.cancelBubble = true;。
w3c是e.prevent()。
说到事件冒泡的应用,有一个很好的事情可以说明那就是事件委托;
事件委托也称为事件代理(Event Delegation),事件委托是一种将事件处理程序绑定到一个父元素上,而不是将事件处理程序绑定到每个子元素上的技术。通过事件委托,可以减少事件处理程序的数量,提高性能和代码的可维护性
事件委托正是利用事件流的冒泡特性,将本来要绑定到多个元素的事件函数,委托到了其祖先元素上。
//事件代理 节约内存 提升性能(不需要注销子节点)
let ul = document.getElementById("ul");
ul.addEventListener("click", (event) => {
console.log(event.target.innerHTML);
})