父组件:
<template><div><treeVue :treeData="treeData"></treeVue></div> </template><script setup lang="ts"> import { reactive } from "vue"; import treeVue from "./tree.vue";interface Tree {name: string,checked: boolean,children?: Tree[] }const treeData = reactive<Tree[]>([{name: "1",checked: false,children: [{name: "1-1",checked: false,},{name: "1-2",checked: true,},],},{name: "2",checked: false,},{name: "3",checked: false,children: [{name: "3-1",checked: false,children: [{name: "3-1-1",checked: false,},{name: "3-1-2",checked: false,},],},{name: "3-2",checked: false,},],}, ]); </script><style scoped> </style>
子组件:
<template><!-- 递归组件使用点击事件,需要阻止冒泡 --><div @click.stop="clickTap(item, $event)" class="tree" v-for="item in treeData"><input type="checkbox" v-model="item.checked"><span>{{ item.name }}</span><!-- 可以使用文件名,不需要引入,如果想修改名称的话,需要自定义name --><!-- 第一种 --><tree v-if="item?.children?.length" :treeData="item?.children"></tree><!-- 第二种 --><!-- <aaaaaa v-if="item?.children?.length" :treeData="item?.children"></aaaaaa> --></div> </template> <!-- 第二种 --> <!-- <script lang="ts"> export default {name: 'aaaaaa' } </script> --> <script setup lang="ts"> interface Tree {name: string,checked: boolean,children?: Tree[] } defineProps<{treeData?: Tree[] }>(); const clickTap = (item, e) => {console.log(item);console.log(e.target); } </script><style scoped> .tree {margin-left: 20px; } </style>
递归组件可以直接使用组件名称,不需要引入,如需要引入,则定义组件name,使用name名称
第一种,直接使用tree.vue名称引入
<!-- 第一种 --> <tree v-if="item?.children?.length" :treeData="item?.children"></tree>
第二种,定义name,使用name名称引入
<!-- 第二种 --> <aaaaaa v-if="item?.children?.length" :treeData="item?.children"></aaaaaa>
<!-- 第二种 --> <script lang="ts"> export default {name: 'aaaaaa' } </script>