父组件:
<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>