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

概述

工程化框架开发项目中,我们会写很多组件,有时候会有如下一个场景: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模块互相引用均有上述问题。

相关推荐
清铎3 分钟前
大模型训练_week3_day15_Llama概念_《穷途末路》
前端·javascript·人工智能·深度学习·自然语言处理·easyui
岛泪17 分钟前
把 el-cascader 的 options 平铺为一维数组(只要叶子节点)
前端·javascript·vue.js
lendsomething34 分钟前
graalvm使用实战:在java中执行js脚本
java·开发语言·javascript·graalvm
Kiyra1 小时前
阅读 Netty 源码关于 NioEventLoop 和 Channel 初始化部分的思考
运维·服务器·前端
冰暮流星1 小时前
javascript的switch语句介绍
java·前端·javascript
小简GoGo2 小时前
前端常用设计模式快速入门
javascript·设计模式
做科研的周师兄2 小时前
【MATLAB 实战】|多波段栅格数据提取部分波段均值——批量处理(NoData 修正 + 地理信息保真)_后附完整代码
前端·算法·机器学习·matlab·均值算法·分类·数据挖掘
da_vinci_x2 小时前
图标量产:从“手绘地狱”到“风格克隆”?Style Reference 的工业化实战
前端·游戏·ui·prompt·aigc·设计师·游戏美术
利刃大大2 小时前
【ES6】变量与常量 && 模板字符串 && 对象 && 解构赋值 && 箭头函数 && 数组 && 扩展运算符 && Promise/Await/Async
开发语言·前端·javascript·es6
天若有情6732 小时前
ES6 模块与 CommonJS 的区别详解
前端·javascript·es6