日常业务代码写久了,已经遗忘了除 addEventListener 之外的事件绑定方式。
所以在看到询问 “在 Vue3 中为什么使用 :onclick 也可以实现事件绑定,以及和 @click 的区别是什么” 的时候。 下意识会以为说是 v-bind 做了处理(其实Vue也确实做了一些处理,但不多)。
而完全没有意识到,其实不加 v-bind 也可以正常实现事件绑定的,比如说:
<template>
<div onclick="alert('Click!')">Click Me</div>
</template>
所以其实就是HTML中的 内联事件处理器 在起作用,并不需要前端框架来介入。
除了以上这个,当然还有一个挂载元素实例上的 onclick 这样 事件处理器属性,这个日常会用的稍微多一些。特别是在手动操作DOM元素的时候。
🤖 关于 Vue 做的额外处理
简单看了一下 vue/core 中关于 v-bind 的实现代码,其实没有做特殊的额外处理。
就是正常在 AST 解析后收集了使用 v-bind 动态绑定的属性,并且使用 createObjectProperty 函数组装成正常的 Property 属性返回。
然后把这些收集了的 props 属性在 createVNode 创建HTML元素时,传入在第二个参数中,最后被处理成了 DOM Property 属性。
至于为什么是 DOM Property 而不是 DOM Attribute (也就是被当成上面提到的事件处理器属性,而不是内联事件处理器),就需要看 shouldSetAsProp 函数了,函数具体实现就不展开描述了。
- 如果想要转换成
DOM Attribute也很简单,去掉:在解析时就会被直接标记成静态属性(NodeTypes.ATTRIBUTE)了,而不是动态绑定的指令类型(NodeTypes.DIRECTIVE)。最后在渲染时的shouldSetAsProp函数中就会被输出成DOM Attribute,显示在HTML元素上了