- 该文章是在学习 小满vue3 课程的随堂记录
- 示例均采用
,且包含
typescript
的基础用法
递归组件
的使用场景,如 无限级的菜单
,接下来就用菜单的例子来学习
<Tree :data="mock" />
// 引入子组件
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,
},
],
},
],
},
];
<div v-for="item in data" style="margin-left: 16px">
<input type="checkbox" v-model="item.checked" />
{{ item.name }}
div>
<script setup lang="ts">
// 这里为了方便直接拷贝过来了,实际项目中要抽离出来复用
interface ITree {
name: string;
checked: boolean;
children?: ITree[];
}
// props 定义
defineProps<{
data?: ITree[];
}>();
</script>
如图,上述代码已经完成了 第一层
菜单数据的渲染:
深层
的菜单数据,就要用到 递归组件
了,递归组件有以下 三种
使用方式自己的文件名
作为 组件名称
,不需要引入当前的文件名称是 Tree.vue
,所以直接使用 Tree
即可
<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>
使用结果如下:
<script lang="ts">
// 再起一个 script(lang必须保持一致),用来定义该组件的 name
export default {
name: "TreeVue",
};
</script>
使用时,就可以用自定义的组件名
<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>
渲染结果一致:
Vue3.3
增加了 defineOptions
方法,用来定义 optionsAPI
中的选项,比如组件名称 name(老一点的 vue 版本要装插件才能使用 defineOptions)<script setup lang="ts">
interface ITree {
name: string;
checked: boolean;
children?: ITree[];
}
defineProps<{
data?: ITree[];
}>();
// 直接在原有的 script 中进行自定义
defineOptions({
name: "Self",
});
</script>
<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>
渲染结果仍然一致,不再赘述