簡(jiǎn)單補(bǔ)充一下vue template模板轉(zhuǎn)為真實(shí)DOM的過(guò)程:
template -> compiler 編譯 -> 渲染函數(shù)render(調(diào)用h函數(shù)) -> Vnode(虛擬節(jié)點(diǎn)) -> 真實(shí)元素 -> 渲染
接下來(lái)將通過(guò)代碼展示實(shí)現(xiàn)過(guò)程:
// index.html
<!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>
<div id="app"></div>
<script src="./render.js"></script>
<script>
let counter = 1
// compiler編譯template后的結(jié)果
const vnode = h("div", {class: 'black'}, [
h("button", {onclick: function() {counter++; console.log(counter)}} , '+1'),
h("h2", null, counter)
])
mount(vnode, document.querySelector('#app'))
</script>
</body>
</html>
// render.js
// h函數(shù)的作用就是將compiler編譯后的模板轉(zhuǎn)為vnode(也就是js對(duì)象)
function h(tag, property, children) {
return {
tag,
property,
children
}
}
// 將vnode轉(zhuǎn)為真實(shí)DOM
function mount(vnode, container) {
// 1. 將tag轉(zhuǎn)為標(biāo)簽
const el = vnode.el = document.createElement(vnode.tag)
// 2. 給標(biāo)簽設(shè)置對(duì)應(yīng)的屬性
if (vnode.property) {
for (const key in vnode.property) {
const value = vnode.property[key]
// 點(diǎn)擊事件
if (key.startsWith("on")) {
el.addEventListener(key.slice(2), value)
console.log(el.click)
} else {
el.setAttribute(key, value)
}
}
}
// 3. 處理children
if (vnode.children) {
if (typeof vnode.children === 'string' || typeof vnode.children === 'number') {
el.textContent = vnode.children
} else {
vnode.children.forEach(item => {
mount(item, el)
});
}
}
// 4. 將節(jié)點(diǎn)掛載到父節(jié)點(diǎn)上
container.appendChild(el)
}
以上呢就是render函數(shù)借助h函數(shù)是怎樣的將compiler編譯后的代碼轉(zhuǎn)為vnode并轉(zhuǎn)為真實(shí)DOM實(shí)現(xiàn)的簡(jiǎn)易過(guò)程。
如有錯(cuò)誤迎变,歡迎指正充尉!