vue实现虚拟dom
Vue 虚拟 DOM 的实现原理
Vue 使用虚拟 DOM(Virtual DOM)来提高渲染性能。虚拟 DOM 是一个轻量级的 JavaScript 对象,它是对真实 DOM 的抽象表示。当数据发生变化时,Vue 会生成一个新的虚拟 DOM 树,然后与旧的虚拟 DOM 树进行比较(diff 算法),找出差异并仅更新真实 DOM 中需要变化的部分。
虚拟 DOM 的核心流程
创建虚拟 DOM
Vue 通过 createElement 函数(通常简写为 h)创建虚拟节点(VNode)。每个 VNode 对应真实 DOM 的一个节点或组件。例如:
const vnode = h('div', { class: 'container' }, [
h('p', { style: { color: 'red' } }, 'Hello Vue')
]);
Diff 算法
当数据变化时,Vue 会生成新的虚拟 DOM 树,并通过 Diff 算法对比新旧 VNode 树的差异。Diff 算法采用同级比较策略,避免跨层级比较,提升效率。
Patch 更新
通过 Diff 算法找到差异后,Vue 调用 patch 函数将变化应用到真实 DOM 上。只有真正需要更新的部分才会被重新渲染。
优化策略
-
静态节点提升
编译阶段标记静态节点,在后续更新中直接复用,避免重复 Diff。 -
事件缓存
对事件监听器进行缓存,避免重复绑定。 -
Key 的作用
为列表项提供唯一的key,帮助 Diff 算法更高效地识别节点的移动和复用。
示例代码
以下是一个简单的虚拟 DOM 实现示例:

// 创建 VNode 的函数
function createElement(tag, props, children) {
return {
tag,
props,
children
};
}
// 渲染 VNode 到真实 DOM
function render(vnode, container) {
const el = document.createElement(vnode.tag);
// 设置属性
for (const key in vnode.props) {
el.setAttribute(key, vnode.props[key]);
}
// 处理子节点
if (typeof vnode.children === 'string') {
el.textContent = vnode.children;
} else if (Array.isArray(vnode.children)) {
vnode.children.forEach(child => {
render(child, el);
});
}
container.appendChild(el);
}
// 使用示例
const vnode = createElement('div', { class: 'container' }, [
createElement('p', { style: 'color: red' }, 'Hello Virtual DOM')
]);
render(vnode, document.body);
与 React 虚拟 DOM 的区别
- Vue 的虚拟 DOM 实现更注重模板编译时的优化(如静态节点提升)。
- Vue 3 引入了编译时优化(如 Block Tree),进一步减少 Diff 的范围。
- React 的虚拟 DOM 更通用,而 Vue 的虚拟 DOM 与模板编译深度集成。
通过虚拟 DOM 技术,Vue 能够在保证开发体验的同时,提供高效的 DOM 更新性能。






