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

概述

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

相关推荐
两个西柚呀4 小时前
未在props中声明的属性
前端·javascript·vue.js
子伟-H56 小时前
App开发框架调研对比
前端
桃子不吃李子6 小时前
axios的二次封装
前端·学习·axios
SteveJrong6 小时前
面试题 - JavaScript
前端·javascript·面试·ecmascript·基础·找工作·红宝书
阿金要当大魔王~~6 小时前
uniapp 页面标签 传值 ————— uniapp 定义 接口
前端·javascript·uni-app·1024程序员节
全栈软件开发7 小时前
uniapp三端影视源码苹果cms自动采集电影视频网站源码前端源码带VIP
前端·uni-app·影视源码
chxii7 小时前
10.4FormData :前端文件上传与表单数据处理的核心工具
前端
AntBlack8 小时前
不当韭菜 : 好像真有点效果 ,想藏起来自己用了
前端·后端·python
楊无好8 小时前
react中props的使用
前端·react.js·前端框架
一个处女座的程序猿O(∩_∩)O8 小时前
Vue-Loader 深度解析:原理、使用与最佳实践
前端·javascript·vue.js