vue中的原生事件

142 阅读1分钟

vue中可以通过@或者v-on的方式绑定事件,也可为其添加修饰符。

new Vue({
  el: '#app',
  template: `<div @click='divClick'><a @clickt='aClick' href=''>点击</a></div>`,
  methods: {
    divClick() {
      console.log('divClick')
    },
    aClick() {
      console.log('aClick')
    },
  }
})

以上例子如果点击a会触发其默认行为,如果href不为空还会进行跳转。除此之外,点击还会继续触发div上绑定的点击事件。

如果通过@click.stop.prevent='aClick'的方式为a标签的点击事件添加修饰符stopprevent,那么就不会触发其a的默认行为,即使href不为空也不会进行跳转,同时,div上的点击事件也不会进行触发。

模板的渲染一般分为编译生成render函数、render函数执行生成vNodepatch进行渲染。下面按照这步骤进行简单分析。

1、render

通过编译生成的render函数:

with(this) {
    return _c('div', {
        on: {
            "click": divClick
        }
    }, [_c('a', {
        attrs: {
            "href": "http://www.baidu.com"
        },
        on: {
            "click": function ($event) {
                $event.stopPropagation();
                $event.preventDefault();
                return aClick($event)
            }
        }
    }, [_v("点击")])])
}

其中divon作为div事件描述。a标签的attrs作为属性描述,on作为事件描述,在描述中.stop被编译成了$event.stopPropagation()来阻止事件冒泡,.prevent被编译成了$event.preventDefault()用来阻止a标签的默认行为。

2、vNode

通过执行Vue.prototype._renderrender函数转换成vNode

3、patch

patch的过程中,当完成$el节点的渲染后会执行invokeCreateHooks(vnode, insertedVnodeQueue)逻辑,其中,针对attrs会将其设置为$el的真实属性,当前例子中会为a标签设置herf属性。针对on会通过target.addEventListener的方式将其处理过的事件绑定到$el上,当前例子中会分别对diva中的click进行处理,再通过addEventListener的方式进行绑定。

总结

vue中的事件,从编译生成render再通过Vue.prototype._render函数执行render到生成vNode,主要是通过on作为描述。在patch渲染阶段,将on描述的事件进行处理再通过addEventListener的方式绑定到$el上。