[Vue] MIni mount and patch function
<style>
.red {color: red;}
.green {color: green;}
</style>
<div id="app"></div>
<script>
function h(tag, props, children) {
return { tag, props, children };
}
function mount(vnode, container) {
const el = vnode.el = document.createElement(vnode.tag)
console.log(vnode)
// props
if (vnode.props) {
for (const key in vnode.props) {
el.setAttribute(key, vnode.props[key])
}
}
// children
if (vnode.children) {
if (typeof vnode.children === 'string') {
el.textContent = vnode.children
} else {
vnode.children.forEach(child => {
mount(child, el)
})
}
}
container.appendChild(el)
}
const vdom = h('div', {class: 'red'}, [
h('span', null, 'hello')
])
mount(vdom, document.getElementById('app'))
function patch(/*old vdom*/n1 , /*new vdom*/ n2 ) {
if (
n1.tag === n2.tag
) {
const el = n2.el = n1.el
// props
const oldProps = n1.props || {}
const newProps = n2.props || {}
for (const key in newProps) {
const oldValue = oldProps[key]
const newValue = newProps[key]
if (oldValue !== newValue) {
el.setAttribute(key, newValue)
}
}
for(const key in oldProps) {
if (!(key in newProps)) {
el.removeAttribute(key)
}
}
// children
const oldChildren = n1.children
const newChildren = n2.children
if (typeof newChildren === 'string') {
if (typeof oldChildren === 'string') {
el.textContent = newChildren
} else {
// oldChildren is array
el.textContent = newChildren
}
} else {
// newChildren is array
if (typeof oldChildren === 'string') {
el.innerHTML = ''
newChildren.forEach(child => {
mount(child, el)
})
} else {
// oldChildren is array
// handle common children
const commonLength = Math.min(oldChildren.length, newChildren.length)
for (let i = 0; i < commonLength; i++) {
patch(oldChildren[i], newChildren[i])
}
// newChildren is longer, handle new children
if (newChildren.length > oldChildren.length) {
newChildren.slice(oldChildren.length).forEach(child => {
mount(child, el)
})
} else if (newChildren.length < oldChildren.length) {
// oldChildren is longer, handle removed children
oldChildren.slice(newChildren.length).forEach(child => {
el.removeChild(child.el)
})
}
}
}
} else {
// replace
}
}
const vdom2 = h('div', {class: 'green'}, [
h('span', null, 'changed!')
])
patch(vdom, vdom2)
</script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-12-03 [Javascript Performance] Optimisation and deoptimization
2022-12-03 [Javascript Performance] How to benchmark code performance
2022-12-03 [Typescript] 125. Extreme - Object Key Paths
2021-12-03 [AWS] Using EC2 Roles and Instance Profiles in AWS
2019-12-03 [Algorithm] 122. Best Time to Buy and Sell Stock II
2019-12-03 [ARIA] Create an Accessible Tooltip on a Text Input
2019-12-03 [Algorithm] 121. Best Time to Buy and Sell Stock