vue实现dom更新
Vue 实现 DOM 更新的核心机制
Vue 通过响应式系统和虚拟 DOM实现高效的 DOM 更新。以下是具体实现方式:
响应式数据绑定
Vue 使用 Object.defineProperty 或 Proxy(Vue 3)劫持数据属性的访问和修改。当数据变化时,触发 setter 函数,通知依赖该数据的 Watcher 实例。
// 简化版响应式原理
function defineReactive(obj, key) {
let val = obj[key]
const dep = new Dep() // 依赖收集容器
Object.defineProperty(obj, key, {
get() {
dep.depend() // 收集当前依赖
return val
},
set(newVal) {
if (newVal === val) return
val = newVal
dep.notify() // 通知更新
}
})
}
虚拟 DOM Diff 算法
当数据变化触发更新时,Vue 会重新渲染虚拟 DOM 树,通过 Diff 算法对比新旧虚拟 DOM:

- 同级比较:只比较同层级的节点,不跨层级
- Key 优化:通过
key标识节点身份,复用相同 key 的节点 - 差异更新:仅对实际变化的节点进行 DOM 操作
// 虚拟 DOM 示例结构
{
tag: 'div',
props: { id: 'app' },
children: [
{ tag: 'span', text: 'Hello' }
]
}
异步更新队列
Vue 通过 nextTick 实现异步批量更新,避免频繁的 DOM 操作:
// 更新流程
dataChange -> Watcher.notify() -> queueWatcher() -> nextTick(flushSchedulerQueue)
手动触发更新的方法
强制更新组件
使用 $forceUpdate() 方法可跳过优化直接重新渲染组件:

this.$forceUpdate()
使用 Key 强制重新渲染
通过改变 key 值强制组件重建:
<template>
<ChildComponent :key="reloadKey" />
</template>
<script>
export default {
data() {
return { reloadKey: 0 }
},
methods: {
forceRerender() {
this.reloadKey += 1
}
}
}
</script>
数组更新检测
对于数组操作,需要使用变异方法或 $set 触发更新:
// 正确方式
this.items.splice(index, 1, newItem)
this.$set(this.items, index, newValue)
// 错误方式(不会触发视图更新)
this.items[index] = newValue
性能优化建议
- 合理使用
v-if和v-show:频繁切换用v-show,条件稳定用v-if - 避免大范围 v-for:对长列表使用虚拟滚动或分页
- 减少计算属性依赖:复杂计算考虑使用缓存或方法
- 组件拆分:将频繁更新的部分隔离到子组件
以上机制共同构成了 Vue 高效 DOM 更新的核心,开发者应理解其原理以编写更优化的代码。






