组件循环引用依赖问题处理

概述

工程化框架开发项目中,我们会写很多组件,有时候会有如下一个场景:A组件包含B组件,B组件又依赖A组件,形成了循环引用的问题,这样的组件最好在渲染的时候会导致渲染报错。

示例

有如下两个组件,互相引用依赖

ProductInfo.vue组件

js 复制代码
<template>
  <Products v-for="item in data" :data="item"></Products>
</template>

<script>
import { defineComponent } from "vue";
import Products from "./Products.vue";
console.log("Products--", Products);

export default defineComponent({
  name: "ProductInfo",
  components: { Products },
  props: {
    data: {
      type: Array,
      required: true,
    },
  },
});
</script>

Products.vue组件

js 复制代码
<template>
  <div class="products">
    <div @click="handleAddSub">
      name :
      {{ data.name }}
    </div>
    <div>
      price :
      {{ data.price }}
    </div>
    <div>
      desc :
      {{ data.desc }}
    </div>

    <h2>relateProduct:</h2>

    <ProductInfo :data="dataList"></ProductInfo>
  </div>
</template>

<script>
import ProductInfo from "./ProductInfo.vue";
import { ref, defineComponent } from "vue";

console.log("ProductInfo", ProductInfo);
export default defineComponent({
  name: "Products",
  components: {
    ProductInfo,
  },
  props: {
    data: {
      type: Object,
      required: true,
    },
  },
  setup(props) {
    const dataList = ref([]);
    const handleAddSub = () => {
      dataList.value.push({
        name: props.data.name + "test",
        price: 999,
        desc: "i am test",
      });

      console.log("dataList", dataList);
    };
    return {
      handleAddSub,
      dataList,
    };
  },
});
</script>

app.vue使用

js 复制代码
<script setup lang="ts">
import ProductInfo from "@/components/product/ProductInfo.vue";

const dataList = [
  { name: "apple", price: 100, desc: "i am apple" },
  { name: "banana", price: 200, desc: "i am banana" },
  { name: "orange", price: 300, desc: "i am orange" },
];
</script>

<template>
  <ProductInfo :data = 'dataList'></ProductInfo>
</template>

问题

Products.vue中这里输出组件提示报错页面无法渲染

原因

上面的原因就在于两个组件(模块互相引用),ProductInfo组件开始的时候通过如下导入了Products组件

js 复制代码
import Products from "./Products.vue";

而Products组件中导入了Products组件,在导入代码进入Products组件的时候,由于ProductInfo组件还没执行后面的export default defineComponent({}),因此无法找到,提示报错

js 复制代码
import ProductInfo from "./ProductInfo.vue";

解决方案

方案1:全局注册

直接将两个组件全局注册,然后使用

js 复制代码
//main.js
import ProductInfo from "./ProductInfo.vue";
import Products from "./Products.vue";
app.component(ProductInfo)
app.component(Products)

方案2:异步组件

在运行时候,加载组件,改造Products.vue组件如下,通过异步组件注册动态导入组件

js 复制代码
<template>
  <div class="products">
    <div @click="handleAddSub">
      name :
      {{ data.name }}
    </div>
    <div>
      price :
      {{ data.price }}
    </div>
    <div>
      desc :
      {{ data.desc }}
    </div>

    <h2>relateProduct:</h2>

    <ProductInfo :data="dataList"></ProductInfo>
  </div>
</template>


<script>
// import ProductInfo from "./ProductInfo.vue";
import { ref, defineComponent, defineAsyncComponent } from "vue";

// console.log("ProductInfo", ProductInfo);
export default defineComponent({
  name: "Products",
  components: {
    ProductInfo: defineAsyncComponent(() => import("./ProductInfo.vue")),
  },
  props: {
    data: {
      type: Object,
      required: true,
    },
  },
  setup(props) {
    const dataList = ref([]);
    const handleAddSub = () => {
      dataList.value.push({
        name: props.data.name + "test",
        price: 999,
        desc: "i am test",
      });

      console.log("dataList", dataList);
    };
    return {
      handleAddSub,
      dataList,
    };
  },
});
</script>

总结

上面的问题其实不单单是vue组件导入会出现的问题,只要是模块,js模块互相引用均有上述问题。

相关推荐
mango_mangojuice几秒前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
Days205024 分钟前
简单处理接口返回400条数据本地数据分页加载
前端
Novlan130 分钟前
@tdesign/uniapp 图标瘦身
前端
ManThink Technology34 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
铅笔侠_小龙虾1 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
大模型玩家七七1 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
. . . . .1 小时前
shadcn组件库
前端
2501_944711431 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜2 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
css趣多多2 小时前
ctx 上下文对象控制新增 / 编辑表单显示隐藏的逻辑
前端