vue 父组件 如何监听子组件是否 mounted?

现在有三个组件 parent son grandSon (都是异步加载的)

结构如下
parent.vue

<son msg="son"/>

son.vue

<grandSon msg="grandSon"/>

grandSon.vue

<div>{{msg}}</div>

请问如何在 parent.vue 监听到 son.vue grandSon.vue 都挂载完成的方案?

尝试过 使用 @hook:mounted

但是在多层级的场景下(目前我是三个层级),有没有更优雅的方式?

阅读 5k
3 个回答

首先说下,为什么Vue的设计一开始无法透传,后面才陆续地加入跨父子传输的方式,是因为希望数据流能够单向清晰。但这样也造成了使用上的麻烦。

要完成你的需求有很多种方法。这里提供一种最简单易理解的方法。

我们将通过全局Mixin为每个组件增加上报事件的钩子,并在上层进行收集。
封装成工具函数可以是:

/**
 * @param target {Vue} Vue instance
 * @param callback {(vm: Vue) => void} Callback
 */
function createDescendantComponentListener (target, callback) {
    return function () {
        for (
            let $vm = this.$parent, $root = this.$root;
            $root !== $vm;
            $vm = $vm.$parent
        ) {
            if (target === $vm) {
                callback(this);
                break;
            }
        }
    };
}

/**
 * @param target {Vue} Vue instance
 * @param callback {(vm: Vue) => void} Callback
 */
export function addDescendantComponentBeforeMountListener (target, callback) {
    target.constructor.super.mixin({
        beforeMount: createDescendantComponentListener(target, callback),
    });
}

/**
 * @param target {Vue} Vue instance
 * @param callback {(vm: Vue) => void} Callback
 */
export function addDescendantComponentMountedListener (target, callback) {
    target.constructor.super.mixin({
        mounted: createDescendantComponentListener(target, callback),
    });
}

/**
 * @param target {Vue} Vue instance
 * @param callback {(vms: Vue[]) => void} Callback
 */
export function ensureAllDescendantComponentsMounted (target, callback) {
    const instances = new Set();

    addDescendantComponentBeforeMountListener(
        target,
        instance => {
            instances.add(instance);
        },
    );

    addDescendantComponentMountedListener(
        target,
        instance => {
            const vms = [...instances];
            if (vms.every(instance => instance._isMounted)) {
                callback(vms);
            }
        },
    );
}

vue的挂载顺序本来就是子组件先挂载,父组件后挂载
image.png

用个第三方的eventEmitter或者原生CustomEvent都挺方便

vue2?祖先组件provide一个方法,子级mounted时子级去调用,不过你要怎么只到有多少子级?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题