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

概述

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

相关推荐
做运维的阿瑞5 分钟前
Windows 环境下安装 Node.js 和 Vue.js 框架完全指南
前端·javascript·vue.js·windows·node.js
Dontla2 小时前
Tailwind CSS介绍(现代CSS框架,与传统CSS框架Bootstrap对比)Tailwind介绍
前端·css·bootstrap
yinuo2 小时前
uniapp微信小程序安卓手机Touchend事件无法触发
前端
你的人类朋友4 小时前
【Node】Node.js 多进程与多线程:Cluster 与 Worker Threads 入门
前端·后端·node.js
闲人编程4 小时前
使用Celery处理Python Web应用中的异步任务
开发语言·前端·python·web·异步·celery
excel4 小时前
前端读取文件夹并通过 SSH 上传:完整实现方案 ✅
前端
谢尔登4 小时前
【Nest】日志记录
javascript·中间件·node.js
双向335 小时前
【征文计划】基于Rokid CXR-M SDK 打造AI 实时会议助手:从连接到自定义界面的完整实践
前端
Lei活在当下5 小时前
【业务场景架构实战】6. 从业务痛点到通用能力:Android 优先级分页加载器设计
前端·后端·架构
你的人类朋友5 小时前
什么是基础设施中间件
前端·后端