一、绑定事件的两种方式
addEventListener : js原生事件绑定,累加式绑定,可以给一个元素绑定多个相同事件。
on:js事件绑定,替换式绑定,使用 on 的方式绑定事件,一种事件只能绑定一次,绑定多个相同事件,后面的事件会覆盖前面的事件。
二、主要思考的问题如下:
vue当中,如果我们去在onMounted中去采用dom节点的方式去绑定了一个事件,那么我们需不需要在页面销毁时去将这个绑定的事件销毁呢?
从逻辑上来说的话,是需要的。不然就会导致很多问题!
诸如我在项目中碰到的一个问题,scoll滚动事件
其实常常我们scoll绑定主要是绑定在window上的,但是不免得,我们也会绑定在其他的节点上。
如果说我们当前将scoll事件绑定到了一个小滚动窗口上面,采用的方式是addEventListener这种原生的方式进行绑定的话,在路由单页面的情况下就会导致这样一个问题,因为事件是累加的,我们多个页面绑定的节点或许只可能是他们父组件中的同一个节点,但是我们绑定了多次,就会导致一个事件触发多次的问题,那么这个时候我们就应该在onbeforeUnmount页面销毁之前的生命周期钩子中将这个事件去进行销毁。
onMounted(() => {
document.querySelect('#xxx').addEventListener('scroll',function(){
xxxxxxxx
})
})
// 页面销毁之前
onBeforeUnmount(() => {
document.querySelect('#xxx').removeEventListener('scroll',function(){
xxxxxxxx
})
})
注意上方,我此时并不是给window绑定的scroll事件,而是给单个dom节点绑定的scroll事件,首先代码是没有问题的,当我们去切换路由的时候,当前路由组件也就卸载了,那么onBeforeUnmount事件也就触发了,但是scroll事件却没有销毁,大体的原因如下:
是因为绑定的dom节点设置了css属性overflow:scroll/auto;
从而导致了事件无法销毁,但是我们如果去除了overflow这个属性的话,那么不就没有滚动条了嘛?
三、采用on事件绑定解决问题:
这个时候注意,我们可以用另外一种事件绑定解决当前问题,防止事件多次触发
文章开头,就讲述了两种绑定事件的区别,一种是累加方式的绑定,一种是替换类型的绑定
其实我们主要想要解决的问题是什么呢?就是阻止一个节点,重复绑定多次事件,那么on绑定方式就是可以解决这种问题,因为他是替换式的绑定方式,后绑定的话会替换掉原有的绑定事件,那么这个时候就不会触发上一次绑定的事件了,而是直接替换掉了,问题当然也就解决了。
绑定方式如下:
onMounted(() => {
document.querySelect('#xxx').onclick = function(){
xxxxxxxx
}
})
// 页面销毁之前
onBeforeUnmount(() => {
document.querySelect('#xxx').onclick = null
})