uni-app 组件之间的循环引用 A->B->A 导致 A 不渲染 dom

uni-app 组件之间的循环引用 A->B->A 导致 A 不渲染 dom

开发环境 版本号 项目创建方式
Windows win10 HBuilderX

示例代码:

<template>  
    <view class="page">  
        <b-test></b-test>  
    </view>  
</template>  
<script>  
export default {  
    data() {  
        return {};  
    },  
};  
</script>  
<style lang="scss" scoped>  
.page {  
    width: 100%;  
    height: 100%;  
    padding: 100px;  
}  
</style>  
<template>  
    <view>  
        <text>{{ isChild ? "subAAA" : "AAA" }}</text>  
        <view v-if="!isChild">  
            <b-subtest></b-subtest>  
        </view>  
    </view>  
</template>  

<script>  
export default {  
    name: "b-test",  
    props: {  
        isChild: {  
            type: Boolean,  
            default() {  
                return false;  
            },  
        },  
    },  
    data() {  
        return {};  
    },  

    created() {},  
};  
</script>
<template>  
    <view>  
        <text>subBBB</text>  
        <b-test :isChild="true"></b-test>  
    </view>  
</template>  

<script>  
export default {  
    name: "b-subtest",  
    components: {  
        bTest: () => import("../b-test/b-test"),  
    },  
    data() {  
        return {};  
    },  

    created() {},  
};  
</script>

操作步骤:

预期结果:

AAA
subBBB
subAAA

实际结果:

AAA
subBBB

更多关于uni-app 组件之间的循环引用 A->B->A 导致 A 不渲染 dom的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

兄弟你解决了吗?

更多关于uni-app 组件之间的循环引用 A->B->A 导致 A 不渲染 dom的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这个是不是uniapp不支持啊,我也遇到同样的问题

组件的循环引用用到了异步组件,App端不支持异步组件,需要把组件定义到全局。

循环引用是 Vue 生态中的常见问题,在 uni-app 中同样存在。您遇到的问题正是典型的组件循环引用(A->B->A)导致渲染失败的情况。

问题分析:

  1. b-test 组件中,通过条件渲染引用了 b-subtest 组件
  2. b-subtest 组件中,又异步引用了 b-test 组件(通过 :isChild="true"
  3. 当 Vue 尝试解析组件依赖时,陷入了无限循环:b-testb-subtestb-test → …

解决方案:

方案一:使用同步组件注册(推荐) 将异步导入改为同步导入,避免循环依赖解析时的时序问题:

<!-- b-subtest.vue -->
<script>  
import BTest from "../b-test/b-test.vue";

export default {  
    name: "b-subtest",  
    components: {  
        bTest: BTest,  // 改为同步导入
    },  
    // ... 其他代码
};  
</script>

方案二:调整组件结构设计 重新考虑组件关系,避免循环引用:

  • 将公共逻辑提取到 mixin 或 composable 函数中
  • 使用插槽(slot)来解耦组件依赖
  • 考虑将 b-test 中的子组件逻辑内聚,避免拆分为两个相互引用的组件

方案三:使用动态组件 在父级组件中控制组件渲染,打破循环:

<!-- 父组件中 -->
<template>
    <component :is="currentComponent" :isChild="isChild"></component>
</template>

方案四:延迟渲染 使用 v-ifnextTick 控制渲染时机:

<!-- b-subtest.vue -->
<template>  
    <view>  
        <text>subBBB</text>  
        <b-test v-if="showChild" :isChild="true"></b-test>  
    </view>  
</template>

<script>  
export default {  
    data() {  
        return {
            showChild: false
        };  
    },
    mounted() {
        this.$nextTick(() => {
            this.showChild = true;
        });
    }
};  
</script>
回到顶部