13.5 准备工作

上一节对keep-alive组件的分析,是从我画的一个流程图开始的。如果不想回过头看上一节的内容,可以参考以下的简单总结。

  1. keep-alive是源码内部定义的组件选项配置,它会先注册为全局组件供开发者全局使用,其中render函数定义了它的渲染过程
  2. 和普通组件一致,当父在创建真实节点的过程中,遇到keep-alive的组件会进行组件的初始化和实例化。
  3. 实例化会执行挂载$mount的过程,这一步会执行keep-alive选项中的render函数。
  4. render函数在初始渲染时,会将渲染的子Vnode进行缓存。同时对应的子真实节点也会被缓存起来

那么,当再次需要渲染到已经被渲染过的组件时,keep-alive的处理又有什么不同呢?

13.5.1 基础使用

为了文章的完整性,我依旧把基础的使用展示出来,其中加入了生命周期的使用,方便后续对keep-alive生命周期的分析。

  1. <div id="app">
  2. <button @click="changeTabs('child1')">child1</button>
  3. <button @click="changeTabs('child2')">child2</button>
  4. <keep-alive>
  5. <component :is="chooseTabs">
  6. </component>
  7. </keep-alive>
  8. </div>
  1. var child1 = {
  2. template: '<div><button @click="add">add</button><p>{{num}}</p></div>',
  3. data() {
  4. return {
  5. num: 1
  6. }
  7. },
  8. methods: {
  9. add() {
  10. this.num++
  11. }
  12. },
  13. mounted() {
  14. console.log('child1 mounted')
  15. },
  16. activated() {
  17. console.log('child1 activated')
  18. },
  19. deactivated() {
  20. console.log('child1 deactivated')
  21. },
  22. destoryed() {
  23. console.log('child1 destoryed')
  24. }
  25. }
  26. var child2 = {
  27. template: '<div>child2</div>',
  28. mounted() {
  29. console.log('child2 mounted')
  30. },
  31. activated() {
  32. console.log('child2 activated')
  33. },
  34. deactivated() {
  35. console.log('child2 deactivated')
  36. },
  37. destoryed() {
  38. console.log('child2 destoryed')
  39. }
  40. }
  41. var vm = new Vue({
  42. el: '#app',
  43. components: {
  44. child1,
  45. child2,
  46. },
  47. data() {
  48. return {
  49. chooseTabs: 'child1',
  50. }
  51. },
  52. methods: {
  53. changeTabs(tab) {
  54. this.chooseTabs = tab;
  55. }
  56. }
  57. })

13.5.2 流程图

和首次渲染的分析一致,再次渲染的过程我依旧画了一个简单的流程图。

13.5 准备工作 - 图1