13.5 准备工作

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

    • keep-alive是源码内部定义的组件选项配置,它会先注册为全局组件供开发者全局使用,其中render函数定义了它的渲染过程
    • 和普通组件一致,当父在创建真实节点的过程中,遇到keep-alive的组件会进行组件的初始化和实例化。
    • 实例化会执行挂载$mount的过程,这一步会执行keep-alive选项中的render函数。
    • 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>
  9. var child1 = {
  10. template: '<div><button @click="add">add</button><p>{{num}}</p></div>',
  11. data() {
  12. return {
  13. num: 1
  14. }
  15. },
  16. methods: {
  17. add() {
  18. this.num++
  19. }
  20. },
  21. mounted() {
  22. console.log('child1 mounted')
  23. },
  24. activated() {
  25. console.log('child1 activated')
  26. },
  27. deactivated() {
  28. console.log('child1 deactivated')
  29. },
  30. destoryed() {
  31. console.log('child1 destoryed')
  32. }
  33. }
  34. var child2 = {
  35. template: '<div>child2</div>',
  36. mounted() {
  37. console.log('child2 mounted')
  38. },
  39. activated() {
  40. console.log('child2 activated')
  41. },
  42. deactivated() {
  43. console.log('child2 deactivated')
  44. },
  45. destoryed() {
  46. console.log('child2 destoryed')
  47. }
  48. }
  49. var vm = new Vue({
  50. el: '#app',
  51. components: {
  52. child1,
  53. child2,
  54. },
  55. data() {
  56. return {
  57. chooseTabs: 'child1',
  58. }
  59. },
  60. methods: {
  61. changeTabs(tab) {
  62. this.chooseTabs = tab;
  63. }
  64. }
  65. })

13.5.2 流程图

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

13.5 准备工作 - 图1