在 Vue 开发过程中,通常 Vue 的响应式系统会自动处理数据变化并触发视图更新。但在某些特殊情况下,数据虽然改变,但并不会触发视图更新,这时就需要手动强制组件重新渲染。
1. Vue 2 的 $forceUpdate
在 Vue 2 中,this.$forceUpdate() 方法可以强制组件重新渲染,而 不会 重新创建组件实例(不会触发 beforeDestroy 和 destroyed,也不会触发 created 和 mounted)。
举个 🌰
存在一个 data 对象,包含一个数组,希望在用户点击按钮时,修改数组中的某个元素。但当我们直接修改数组的某个元素时,Vue 不会触发视图更新。
<template>
<div>
<ul>
<li v-for="(item, index) in list" :key="index">{
{ item }}</li>
</ul>
<button @click="updateItem">修改第一项</button>
</div>
</template>
<script>
export default {
data() {
return {
list: ['苹果', '香蕉', '橙子'],
};
},
methods: {
updateItem() {
this.list[0] = '葡萄'; // 修改数组中的元素
console.log('点击按钮,修改数组的第一项为:葡萄🍇');
},
},
};
</script>
展示为:
解释:
在 Vue 2 中,如果直接修改数组中的某个元素(eg:this.list[0] = '葡萄'),Vue 不会触发视图更新。因为 Vue 无法检测到数组中的元素的变化(修改数组的某个元素是原地改变的,不是 Vue 可以追踪的响应式变化)。
解决方法:通过 this.$forceUpdate() 强制让 Vue 重新渲染组件,确保视图与数据一致。
export default {
data() {
return {
list: ['苹果', '香蕉', '橙子'],
};
},
methods: {
updateItem() {
this.list[0] = '葡萄'; // 修改数组中的元素
console.log('点击按钮,修改数组的第一项为:葡萄🍇');
this.$forceUpdate(); // 强制更新视图
},
},
};
为什么使用 $forceUpdate() 呢?
这种情况通常发生在 直接修改数组、对象的某些属性 时,Vue 2 的响应式系统没有办法检测到这些变化,从而导致视图没有及时更新。使用 $forceUpdate() 可以在不改变组件状态的情况下,强制组件重新渲染。
1.1 注意📢
使用 $forceUpdate() 并不是最佳实践,只有在特别需要的时候才使用。尽量利用 Vue 的响应式系统来触发视图更新。比如 Vue.set() 或者 替换整个数组/对象,这样 Vue 就可以正确监听数据变化并自动更新视图。
方法 1:Vue.set()(推荐)
Vue 2 的 Vue.set() 方法可以显式地告诉 Vue 这个属性是响应式的,从而触发视图更新。
export default {
data() {
return {
list: ['苹果', '香蕉', '橙子'],
};
},
methods: {
updateItem() {
this.$set(this.list, 0, '葡萄'); // 使用 Vue.set