vue3——递归组件的使用

  • 该文章是在学习 小满vue3 课程的随堂记录
  • 示例均采用 <script setup>,且包含 typescript 的基础用法

一、使用场景

递归组件 的使用场景,如 无限级的菜单 ,接下来就用菜单的例子来学习

二、具体使用

先把菜单的基础内容写出来再说

父组件

html 复制代码
<Tree :data="mock" />
ts 复制代码
// 引入子组件
import Tree from "../components/17_组件/Tree.vue";

// 菜单的数据格式
interface ITree {
  name: string;
  checked: boolean;
  children?: ITree[];
}
// 数据 mock
const mock: ITree[] = [
  {
    name: "1",
    checked: false,
    children: [
      {
        name: "1-1",
        checked: true,
      },
    ],
  },
  {
    name: "2",
    checked: false,
  },
  {
    name: "3",
    checked: false,
    children: [
      {
        name: "3-1",
        checked: false,
        children: [
          {
            name: "3-1-1",
            checked: true,
          },
        ],
      },
    ],
  },
];

子组件

html 复制代码
<!-- 第一层数据 -->
<div v-for="item in data" style="margin-left: 16px">
  <input type="checkbox" v-model="item.checked" />
  {{ item.name }}
</div>
ts 复制代码
<script setup lang="ts">
// 这里为了方便直接拷贝过来了,实际项目中要抽离出来复用
interface ITree {
  name: string;
  checked: boolean;
  children?: ITree[];
}
// props 定义
defineProps<{
  data?: ITree[];
}>();
</script>

如图,上述代码已经完成了 第一层 菜单数据的渲染:

深层 的菜单数据,就要用到 递归组件 了,递归组件有以下 三种 使用方式

1、直接使用 自己的文件名 作为 组件名称,不需要引入

当前的文件名称是 Tree.vue,所以直接使用 Tree 即可

子组件

html 复制代码
<!-- 第一层数据 -->
<div v-for="item in data" style="margin-left: 16px">
  <input type="checkbox" v-model="item.checked" />
  {{ item.name }}
  <!-- 需要注意:需要按照格式传入子组件要用的数据,并且加上递归的判断条件 -->
  <Tree v-if="item?.children?.length" :data="item.children"></Tree>
</div>

使用结果如下:

2、子组件中再定义一个 script,并暴露出 name

子组件

ts 复制代码
<script lang="ts">
// 再起一个 script(lang必须保持一致),用来定义该组件的 name
export default {
  name: "TreeVue",
};
</script>

使用时,就可以用自定义的组件名

html 复制代码
<!-- 第一层数据 -->
<div v-for="item in data" style="margin-left: 16px">
  <input type="checkbox" v-model="item.checked" />
  {{ item.name }}
  <!-- 深层数据 -->
  <TreeVue v-if="item?.children?.length" :data="item.children"></TreeVue>
</div>

渲染结果一致:

3、使用 defineOptions 自定义组件名

  • Vue3.3 增加了 defineOptions 方法,用来定义 optionsAPI 中的选项,比如组件名称 name(老一点的 vue 版本要装插件才能使用 defineOptions)
  • 与上面第二种思路一致,就是起个名再用

子组件

ts 复制代码
<script setup lang="ts">
interface ITree {
  name: string;
  checked: boolean;
  children?: ITree[];
}
defineProps<{
  data?: ITree[];
}>();

// 直接在原有的 script 中进行自定义
defineOptions({
  name: "Self",
});
</script>
html 复制代码
<!-- 第一层数据 -->
<div v-for="item in data" style="margin-left: 16px">
  <input type="checkbox" v-model="item.checked" />
  {{ item.name }}
  <!-- 深层数据 -->
  <Self v-if="item?.children?.length" :data="item.children"></Self>
</div>

渲染结果仍然一致,不再赘述

相关推荐
有梦想的攻城狮1 天前
从0开始学vue:vue3和vue2的关系
前端·javascript·vue.js·vue3·vue2
全栈小54 天前
【前端】Vue3+elementui+ts,TypeScript Promise<string>转string错误解析,习惯性请出DeepSeek来解答
前端·elementui·typescript·vue3·同步异步
西哥写代码6 天前
基于cornerstone3D的dicom影像浏览器 第二十七章 设置vr相机,复位视图
3d·vue3·vr·cornerstonejs
西哥写代码7 天前
基于cornerstone3D的dicom影像浏览器 第二十五章 自定义VR调窗工具
javascript·3d·vue3·vr·cornerstonejs
放逐者-保持本心,方可放逐8 天前
浅谈 JavaScript 性能优化
开发语言·javascript·性能优化·vue3·v-memo·vue3性能优化·v-once
西哥写代码9 天前
基于cornerstone3D的dicom影像浏览器 第二十四章 显示方位、坐标系、vr轮廓线
javascript·3d·vue3·vr·dicom·cornerstonejs
西哥写代码10 天前
基于cornerstone3D的dicom影像浏览器 第二十三章 mpr预设窗值与vr preset
javascript·3d·vue3·dicom·cornerstonejs
linweidong11 天前
汇量科技前端面试题及参考答案
webpack·vue3·react·前端面试·hooks·懒加载·flex布局
EndingCoder12 天前
从零基础到最佳实践:Vue.js 系列(9/10):《单元测试与端到端测试》
前端·javascript·vue.js·性能优化·单元测试·vue3
blues_C16 天前
二、【环境搭建篇】:Django 和 Vue3 开发环境准备
后端·python·django·vue3·测试平台