建议先阅读下面的文章:
条件渲染 — Vue.jscn.vuejs.org![573ab6712c0ae20b3f127a6f18c7d372.png](https://i-blog.csdnimg.cn/blog_migrate/e7f4390b7dd4c6f8ca3960aa7060f046.jpeg)
用vue的时候,如果你开发的页面有很多的局部状态,那么你很大几率会遇到组件重渲染的烦恼。
举个例子:
![5b349b5e13f29760a7c97e9a24ebba69.png](https://i-blog.csdnimg.cn/blog_migrate/6aa6ec9fb97b23abc1b2617d464fe029.jpeg)
这是一个逻辑很复杂的web视频编辑器,用户可以在各个编辑项目之间来回切换。当用户进行项目切换的时候,我们一般的做法是,调用这个编辑器组件的fetchData方法,让所有相关数据重新拉取并重新赋值。得益于vue的响应式系统,页面中的各个元素会使用新的data进行渲染。
但这种渲染只满足了一半的需要。虽然props传递的数据被重新渲染了,但各个子组件的局部状态还保留着。如上图所示,我们将时间轴拉到了4s的位置,这个4s是时间轴组件自己保存的。那么当新的数据进行渲染时,时间轴仍然会处于4s的位置,这显然不符合要求。另外,页面中还会有input框,也会保留着局部状态。这是vue为了性能,重用了我们的相同dom tree中的dom元素。
这时候,思路有3种:
- 通过ref拿到各个涉及局部状态的元素,在切换项目时手动重置
- 在各个涉及局部状态的组件中,watch一个独特的prop,当prop变化时,重置自身的所有局部状态。
- 在最外层的组件使用key
这篇文章主要是谈论第三种方法,通过key来达成组件重渲染。
我们可以在最外层的编辑器框架组件(假如名叫 <Editor>
)上,使用 :key
属性来标记我们何时需要组件进行完整的重渲染。对于这个例子,我们使用 projectId
。一旦新的数据回来,projectId
就会改变,改变之后,所有从属于 <Editor>
的子组件,都会 destroy并重新 mount。那么就达成了我们清理局部状态的目的,并且从编程思路来说,这时候重渲染<Editor>
也是更符合逻辑的。
代码就不多举例了,开头的那个链接足够清晰。