别再用this.$forceUpdate()了!—性能优化篇
起因是接手公司之前外包的项目做项目优化,代码看着一言难尽,然后看代码时,发现了这个api:this.$forceUpdate()
,这是什么?
🎈介绍
这里官网介绍很简单,
vm.$forceUpdate()
示例:
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
还有一段介绍,但是是用于强制更新这一方法的
如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事。
你可能还没有留意到数组或对象的变更检测注意事项,或者你可能依赖了一个未被 Vue 的响应式系统追踪的状态。
然而,如果你已经做到了上述的事项仍然发现在极少数的情况下需要手动强制更新,那么你可以通过 $forceUpdate来做这件事。
就是说这个方法是用来强制更新的!但是官网说你很可能是你的问题,你哪个地方做错了!
🧨弊端
$forceUpdate()会迫使 Vue 实例重新渲染,所以就会有一个问题,那就是重新渲染dom,造成性能压力,而且绕过了vue的正常响应式系统,就抛弃了响应式了,那就有点因噎废食了。
注意事项
$forceUpdate()会触发beforeUpdate
和updated
生命周期
$forceUpdate()只会影响实例本身和插入插槽内容的子组件
🎆解决实例
项目原先代码中,先进行遍历catchs数组中,修改每个对象中的active属性,随后进行更改为false,然后再传参进来的值对应的active值修改为true,原来的兄弟可能看,数据变了怎么不更新啊,没有排查出问题,直接全部重新渲染,真是简单痛快呀。
thisCatch(index) {
this.catchs.forEach((element,index) => {
element.active = false
})
this.catchs[index].active = true
this.$forceUpdate()
},
那就轮到我优化了,首先发现一个点是catchs数组中对象对应的值没有active这个属性,而vue2中响应式就有一个缺陷就是新增属性没有响应式。
所以到这就是两个方法,给默认值或者添加值让它有响应式
默认值好理解,实现响应式其实也挺简单就是使用$set
thisCatch(index) {
this.catchs.forEach((element,index) => {
this.$set(this.days[index], 'active', false);
})
this.$set(this.days[index], 'active', true);
},
很简单就解决了问题,所以其实就正如官网说的😂
如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事。