• 5.4 建立组件联系

    5.4 建立组件联系

    日常开发中,我们可以通过vm.$parent拿到父实例,也可以在父实例中通过vm.$children拿到实例中的子组件。显然,Vue在组件和组件之间建立了一层关联。接下来的内容,我们将探索如何建立组件之间的联系。

    不管是父实例还是子实例,在初始化实例阶段有一个initLifecycle的过程。这个过程会把当前实例添加到父实例的$children属性中,并设置自身的$parent属性指向父实例。举一个具体的应用场景:

    1. <div id="app">
    2. <component-a></component-a>
    3. </div>
    4. Vue.component('component-a', {
    5. template: '<div>a</div>'
    6. })
    7. var vm = new Vue({ el: '#app'})
    8. console.log(vm) // 将实例对象输出

    由于vue实例向上没有父实例,所以vm.$parentundefinedvm$children属性指向子组件componentA 的实例。

    5.4 建立组件联系 - 图1

    子组件componentA$parent属性指向它的父级vm实例,它的$children属性指向为空

    5.4 建立组件联系 - 图2

    源码解析如下:

    1. function initLifecycle (vm) {
    2. var options = vm.$options;
    3. // 子组件注册时,会把父组件的实例挂载到自身选项的parent上
    4. var parent = options.parent;
    5. // 如果是子组件,并且该组件不是抽象组件时,将该组件的实例添加到父组件的$parent属性上,如果父组件是抽象组件,则一直往上层寻找,直到该父级组件不是抽象组件,并将,将该组件的实例添加到父组件的$parent属性
    6. if (parent && !options.abstract) {
    7. while (parent.$options.abstract && parent.$parent) {
    8. parent = parent.$parent;
    9. }
    10. parent.$children.push(vm);
    11. }
    12. // 将自身的$parent属性指向父实例。
    13. vm.$parent = parent;
    14. vm.$root = parent ? parent.$root : vm;
    15. vm.$children = [];
    16. vm.$refs = {};
    17. vm._watcher = null;
    18. vm._inactive = null;
    19. vm._directInactive = false;
    20. // 该实例是否挂载
    21. vm._isMounted = false;
    22. // 该实例是否被销毁
    23. vm._isDestroyed = false;
    24. // 该实例是否正在被销毁
    25. vm._isBeingDestroyed = false;
    26. }

    最后简单讲讲抽象组件,在vue中有很多内置的抽象组件,例如<keep-alive></keep-alive>,<slot><slot>等,这些抽象组件并不会出现在子父级的路径上,并且它们也不会参与DOM的渲染。