vue递归组件

发布于:2023-09-15 ⋅ 阅读:(136) ⋅ 点赞:(0)

父组件:

<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>