13.4 抽象组件

这一节的最后顺便提一下上文提到的抽象组件的概念。Vue提供的内置组件都有一个描述组件类型的选项,这个选项就是{ astract: true },它表明了该组件是抽象组件。什么是抽象组件,为什么要有这一类型的区别呢?我觉得归根究底有两个方面的原因。

  1. 抽象组件没有真实的节点,它在组件渲染阶段不会去解析渲染成真实的dom节点,而只是作为中间的数据过渡层处理,在keep-alive中是对组件缓存的处理。
  2. 在我们介绍组件初始化的时候曾经说到父子组件会显式的建立一层关系,这层关系奠定了父子组件之间通信的基础。我们可以再次回顾一下initLifecycle的代码。
  1. Vue.prototype._init = function() {
  2. ···
  3. var vm = this;
  4. initLifecycle(vm)
  5. }
  6. function initLifecycle (vm) {
  7. var options = vm.$options;
  8. var parent = options.parent;
  9. if (parent && !options.abstract) {
  10. // 如果有abstract属性,一直往上层寻找,直到不是抽象组件
  11. while (parent.$options.abstract && parent.$parent) {
  12. parent = parent.$parent;
  13. }
  14. parent.$children.push(vm);
  15. }
  16. ···
  17. }

子组件在注册阶段会把父实例挂载到自身选项的parent属性上,在initLifecycle过程中,会反向拿到parent上的父组件vnode,并为其$children属性添加该子组件vnode,如果在反向找父组件的过程中,父组件拥有abstract属性,即可判定该组件为抽象组件,此时利用parent的链条往上寻找,直到组件不是抽象组件为止。initLifecycle的处理,让每个组件都能找到上层的父组件以及下层的子组件,使得组件之间形成一个紧密的关系树。

13.5 小结

这一节介绍了Vue内置组件中一个最重要的,也是最常用的组件keep-alive,在日常开发中,我们经常将keep-alive配合动态组件is使用,达到切换组件的同时,将旧的组件缓存。最终达到保留初始状态的目的。在第一次组件渲染时,keep-alive会将组件Vnode以及对应的真实节点进行缓存。而当再次渲染组件时,keep-alive是如何利用这些缓存的?源码又对缓存进行了优化?并且keep-alive组件的生命周期又包括哪些,这些疑问我们将在下一节一一展开。