注册事件的实现方式很简单,重构为通用代码的思路很巧妙
实现事件注册
App.js
这是正常使用结构,实现思路就是从props下手,因为是从props里传过来的
export const App = {
// 没搞编译,所以template不写,写render就行
render() {
// 返回虚拟VNode
return h('div',
{
id: 'root',
class: ['bgc-red', 'font-blue'],
// 事件
onClick() {
console.log('click')
}
},
`hi,${this.msg}`
)
},
setup() {
// composition api
return {
msg: 'mini-vue'
}
}
}
renderer.ts
找到我们在render里处理props的地方,然后进行进一步处理,我们是在mountElement函数中处理的props
function mountElement(vnode: any, container: any) {
const { type, props, children, shapeFlag } = vnode
const el = (vnode.el = document.createElement(type))
// children
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
el.textContent = children
}
else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
mountChildren(vnode, el)
}
// props
for (const key in props) {
const value = props[key]
const isOn = (key) => /^on[A-Z]/.test(key)
if (isOn(key)) {
const event = key.slice(2).toLowerCase()
el.addEventListener(event, value)
} else {
el.setAttribute(key, value)
}
}
container.append(el)
}
事件名称都是以on[大写]的格式,所以可以利用正则匹配,测试通过后,进行分割再进行小写转换,就得到了事件名称,回调就是props里的事件注册的函数,所以就是value,直接放进去就行,对正则不熟悉的码友也可以使用映射
这里使用正则匹配要比多分支if判断要来得快,比映射也更简单高效
结语
下一章就是处理组件props逻辑了,祝大家学有所成