准备 demo
App.js
export const App = {
render(){
return h(
'div',
{
onClick(){
console.log('click')
}
},
'Hello, World!'
)
}
}
给vnode1的props添加以on开头的驼峰式函数,必须对应元素的原生事件名
具体实现
runtime-core/renderer.js
function mountElement(vnode, container) {
const el = document.createElement(vnode.type)
const { children } = vnode
if (typeof children === 'string') {
el.textContent = children
} else if (Array.isArray(children)) {
children.forEach(v => {
patch(v, el)
})
}
const { props } = vnode
for(const key in props){
+ if (key === 'onClick') {
+ el.addEventListener('click', props[key])
+ } else {
el.setAttribute(key, props[key])
+ }
}
container.append(el)
}
事件在初始化元素设置属性中处理
先假设我们只有click事件,只需要判断key为事件则使用addEventListener注册事件,下面改成更通用的实现
通用实现
runtime-core/renderer.js
function mountElement(vnode, container) {
const el = document.createElement(vnode.type)
const { children } = vnode
if (typeof children === 'string') {
el.textContent = children
} else if (Array.isArray(children)) {
children.forEach(v => {
patch(v, el)
})
}
const { props } = vnode
+ const isOn = (key) => /^on[A-Z]/.test(key)
for(const key in props){
+ if (isOn(key)) {
+ const event = key.slice(2).toLowerCase()
+ el.addEventListener(event, props[key])
} else {
el.setAttribute(key, props[key])
}
}
container.append(el)
}
判断key名是否符合on开头的规则,符合则提取on后面的事件名进行注册