<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function renderer(vnode, container) {
// 使用vnode.tag作为标签名
const el = document.createElement(vnode.tag)
// 遍历vnode.props,将属性,事件添加到dom元素
for(const key in vnode.props) {
if(/^on/.test(key)) {
el.addEventListener(
key.substr(2).toLowerCase(), // 将事件名 onClick => click
vnode.props[key] // 添加处理函数
)
}
}
// 处理children
if(typeof vnode.children == 'string') {
// 如果children是字符串,则他是文本节点
el.appendChild(document.createTextNode(vnode.children))
} else if (Array.isArray(vnode.children)) {
// 如果不是 则递归调用renderer函数
vnode.children.forEach(child => {
renderer(child, el)
});
}
// 将虚拟dom挂载到真实dom上
container.appendChild(el)
}
const vnode ={
tag: 'div',
props: {
onClick:() => alert('hello')
},
children: 'click me'
}
renderer(vnode, document.body)
/*
渲染器的整体思路:
1)创建元素,将vnode的tag作为标签,创建dom元素
2)为元素添加事件和属性,遍历vnode.props,如果key是以on开头,则说明他是一个事件,然后添加到元素上
3)处理children,判断children的类型,如果是string,则说明是文本节点,如果是个array,则递归调用renderer函数
*/
</script>
</body>
</html>
【读书笔记】vue.js设计与实现--初识渲染器
于 2022-04-07 22:35:34 首次发布