在 Vue 里,通常数据变化会自动触发虚拟 DOM 的更新,但在某些特殊情形下,你可能需要手动更新虚拟 DOM。下面为你介绍不同 Vue 版本中手动更新虚拟 DOM 的方法:
Vue 2.x
1. 使用 this.$forceUpdate()
this.$forceUpdate()
是 Vue 2 实例的一个方法,调用它会强制组件重新渲染,也就是手动触发虚拟 DOM 的更新。不过需要注意,这只是重新运行渲染函数并更新虚拟 DOM,最终更新到真实 DOM 还是依赖于虚拟 DOM 的 Diff 算法。
<template>
<div>
<p>{
{ message }}</p>
<button @click="forceUpdateDOM">手动更新</button>
</div>
</template>
<script>
export default {
data() {
return {
message: '初始消息'
};
},
methods: {
forceUpdateDOM() {
// 手动更新数据
this.message = '手动更新后的消息';
// 强制组件重新渲染
this.$forceUpdate();
}
}
};
</script>
注意事项
this.$forceUpdate()
会忽略数据是否真的发生变化,直接强制重新渲染组件,所以频繁使用可能会影响性能。- 它不会影响子组件,只有当前调用该方法的组件会重新渲染。
Vue 3.x
1. 使用 markRaw
和 reactive
结合手动更新
在 Vue 3 中,响应式系统有了较大改变,主要使用 reactive
和 ref
来创建响应式数据。若要手动更新虚拟 DOM,可以借助 markRaw
让对象不具备响应式特性,然后手动更新数据并重新赋值。
<template>
<div>
<p>{
{ state.message }}</p>
<button @click="manualUpdate">手动更新</button>
</div>
</template>
<script setup>
import { reactive, markRaw } from 'vue';
// 创建一个非响应式对象
const rawState = {
message: '初始消息'
};
// 使用 markRaw 标记对象,使其不具备响应式特性
const state = reactive(markRaw(rawState));
const manualUpdate = () => {
// 手动更新数据
state.message = '手动更新后的消息';
};
</script>
2. 使用 triggerRef
(针对 ref
创建的数据)
如果使用 ref
创建响应式数据,当手动修改 .value
后,可以使用 triggerRef
手动触发更新。
<template>
<div>
<p>{
{ count }}</p>
<button @click="manualUpdateCount">手动更新计数</button>
</div>
</template>
<script setup>
import { ref, triggerRef } from 'vue';
const count = ref(0);
const manualUpdateCount = () => {
// 手动修改 ref 的值
count.value++;
// 手动触发更新
triggerRef(count);
};
</script>
手动更新虚拟 DOM 通常是在常规响应式机制无法满足需求时使用,使用时要谨慎,因为不合理的手动更新可能会破坏响应式系统的正常工作,还可能影响性能。