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