重排和重绘
我们知道,Vue的diff算法是这样的:
- 对比标签
- 对比key
- 递归对比children的标签和key
- 如果上面三者有一个不一样,就会导致重排。
- 如果说是content、prop改变,会导致重绘。
key的作用
如果两个tab页同时使用同一个组件,tab1组件里面的数据内容会展示在tab2中。这是因为组件没有销毁和重新构建。
解决办法是:给组件加上key
当加上key之后,我们发现还存在一个问题,即是,tab1和tab2切换之后,组件数据内容是会丢失的。这时候我们想到了keep-alive。这样,无论怎么切换,都会返回之前的结果。
keep-alive工作机制
它会维护一个类似Map的结构,由key映射出具体的渲染函数,并且对渲染函数进行返回。
key的选取
源码中写到:
如果组件有key值,那么就会选取组件的key值,成为keep-alive中Map里面的key。因此我们可以得知:key的优先级最高。如果没有key的值,会取type的值。
key优先级最高导致的后果
如果说tab1和tab2组件绑定一样的key,那么组件就不会销毁和重建。状态和数据仍然会共享。tab1组件中的数据仍然会出现在tab2中。
渲染函数
渲染函数的功能是返回虚拟DOM对象。是在onBeforeMounted的时候调用。因此,渲染函数一定会在onMounted之前调用。
keep-alive的流程
- 执行setup函数
- 通过默认插槽拿到组件内容,包括里面的key、type等。
- 拿到key
- 将key赋给全局变量
- cacheSubTree对key和实例进行缓存。