目录
- Vue 自定义指令的执行机制
- 前情提要
- DOM绑定
- 源码
- directive
- 为什么先调用模版绑定的方法,再调用指令的方法
- 总结
Vue 自定义指令的执行机制
version: 2.6.14
前情提要
某日,业务需要我需要在按钮点击之前验证某些条件,如果不符合即不执行click内的业务代码。思前想后,写一个指令不就可以了。做到既不改动原有的业务代码,又可以移植。
<template>
<button v-capture @click="handleClick">button</button>
</template>
<script>
export default {
methods: {
handleClick(){
console.log(1)
}
},
directives: {
capture: {
bind(el) {
el.captureHandler = (e) => {
// 验证条件
console.log(2)
e.stopPropagation()
};
el.addEventListener("click", el.captureHandler);
},
unbind(el) {
el.removeEventListener("click", el.captureHandler);
}
}
}
}
</script>
以上就是伪代码,乍一看没啥问题。
实际一运行,发现1和2都打印出来了,而且1还是在2之前运行的。
这样一看模版上绑定的事件执行是在自定义指令绑定事件之前的。
翻开谷歌,也没有找到相关案例。
DOM绑定
我们都知道vue的SFC最终还是会被编译成js文件,最终模板会被编译成vnode,
元素上绑定的事件会转换成vnode上的一个对象
{
// ....
on: {
click: 'handleClick'
}
}
源码
那就找一找这个对象在哪边使用的
runtime中搜索addEventListener, 因为这个事件绑定上DOM中才有的事件,所以只会在web中了
// src/platforms/web/runtime/modules/events.js
export default {
create: updateDOMListeners,
update: updateDOMListeners,
destroy: (vnode: VNodeWithData) => updateDOMListeners(vnode, emptyNode)
}
具体实现就先不管
updateDOMListeners中通过调用了updateListeners方法,把事件绑定到元素上去
还有就是返回了一个对象,包括create、update、destroy, 这不是很像vue的生命周期函数命名嘛
根据文件依次向上找
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)