递归组件

第一种方式,直接自己调用自己

Tree.vue

<template>
<div class="tree">
<div v-for="(item, index) in data" :key="item.name">
每一层 {{ item.name }}
<Tree v-if="item?.children?.length" :data='item.children' />
</div>
</div>
</template> <script setup lang="ts">
//递归的第一种方式 直接引入自己
import Tree from './Tree.vue'
import { TreeList } from '../ts/type'
type Props = {
data?: TreeList[]
}
defineProps<Props>();
</script> <style scoped>
.tree {
margin-left: 20px;
border-left: 2px #01847f dashed;
}
</style>

App.vue 里模拟树形数据,使用递归组件

<template>
<div>
<Tree :data='data'/>
</div>
</template> <script setup lang="ts">
import Tree from './components/Tree.vue'
import { reactive } from 'vue'
import {TreeList } from './ts/type'
const data = reactive<TreeList[]>([
{
name: 'no.1',
children: [
{
name: 'no.1-1',
children: [
{
name: 'no.1-1-1',
children:[]
}
]
},
],
}, {
name:'no.2'
}, {
name: 'no.3',
children: [{
name:'no.3-1'
}]
} ])
</script> <style scoped></style>

type.ts 属性数据的结构

export type TreeList = {
name: string //名称
icon?: string //图标可有可无
children?: TreeList[] | [] //子节点 可有可无 还可能传空数组
}

第二种方式,export 一个name出去

第二种方式 就是像vue2 一样 export一个name出去

但是setup 语法糖下没办法使用 export

我们只需要再定义一个script标签就可以了

<template>
<div class="tree">
<div v-for="(item, index) in data" :key="item.name">
每一层 {{ item.name }}
<Tree v-if="item?.children?.length" :data='item.children' />
</div>
</div>
</template> <script setup lang="ts">
import { TreeList } from '../ts/type'
type Props = {
data?: TreeList[]
}
defineProps<Props>();
</script>
<!--
第二种方式 就是像vue2 一样 export一个name出去
但是setup 语法糖下没办法使用 export
我们只需要再定义一个script标签就可以了
-->
<script lang="ts">
export default {
name:'Tree'
}
</script> <style scoped>
.tree {
margin-left: 20px;
border-left: 2px #01847f dashed;
}
</style>

效果图

我们还可以给树形递归的组件添加参数传递事件

要注意在树形组件的里层也得添加自定义事件

并且这个自定义事件传的函数很有讲究

Tree.vue

<template>
<div class="tree">
<div @click.stop="clickTreeItem(item)" v-for="(item, index) in data" :key="item.name">
每一层 {{ item.name }}
<Tree @get-tree-item="clickTreeItem" v-if="item?.children?.length" :data='item.children' />
<!-- Tree 组件不添加这个自定义事件的话 那么就只有最外层的根节点会向外传递数据 -->
<!-- 注意此处派发的函数clickTreeItem没有传item参数了如果传了就相当于给树形组件(递归组件)的上级派发信息 没办法从外部拿到子节点所传递的数据了 -->
<!-- @get-tree-item="clickTreeItem(item)" 写成这种形式的话 递归组件会依次向上层传递事件 -->
<!-- 不传item的执行结果如下 -->
<!--子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
父组件得到的item Proxy {name: 'no.1-1-1', children: Array(0)} -->
<!-- 传item的执行的结果如下 -->
<!-- 子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
子组件派发的item Proxy {name: 'no.1-1', children: Array(1)}
子组件派发的item Proxy {name: 'no.1', children: Array(1)}
父组件得到的item Proxy {name: 'no.1', children: Array(1)} -->
</div>
</div>
</template> <script setup lang="ts">
import { TreeList } from '../ts/type'
type Props = {
data?: TreeList[]
}
defineProps<Props>(); const emit = defineEmits(['getTreeItem'])
const clickTreeItem=(item:TreeList)=>{
console.log('子组件派发的item', item)
emit('getTreeItem',item)
}
</script>
<!--
第二种方式 就是像vue2 一样 export一个name出去
但是setup 语法糖下没办法使用 export
我们只需要再定义一个script标签就可以了
-->
<script lang="ts">
export default {
name:'Tree'
}
</script> <style scoped>
.tree {
margin-left: 20px;
border-left: 2px #01847f dashed;
}
</style>

App.vue

<template>
<div>
<Tree :data='data' @get-tree-item="getTreeItem"/>
</div>
</template> <script setup lang="ts">
import Tree from './components/Tree.vue'
import { reactive } from 'vue'
import {TreeList } from './ts/type'
const data = reactive<TreeList[]>([
{
name: 'no.1',
children: [
{
name: 'no.1-1',
children: [
{
name: 'no.1-1-1',
children:[]
}
]
},
],
}, {
name:'no.2'
}, {
name: 'no.3',
children: [{
name:'no.3-1'
}]
} ]) const getTreeItem = (item:TreeList) => {
console.log('父组件得到的item',item)
}
</script> <style scoped></style>

最新文章

  1. 设计模式之合成/聚合利用原则(CARP)
  2. androidstdio偶遇一
  3. 安装springboot时遇到 LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.问题
  4. Android Runtime
  5. supersr--class_copyIvarList和class_copyPropertyList的区别
  6. treap 1296 营业额统计
  7. Educational Codeforces Round 5 E. Sum of Remainders (思维题)
  8. Linux大量TIME_WAIT的解决办法
  9. 【grunt整合版】学会使用grunt打包前端代码
  10. .Net Core Session使用
  11. Spring Boot - Font Awesome OTS parsing error: Failed to convert 字体加载失败
  12. 【集训第二天&#183;翻水的老师】--ac自动机+splay树
  13. 如何运用git实现版本控制
  14. exactly-once和kafka
  15. Spring@Autowired注解与自动装配(转发)
  16. CnPack实用功能推荐
  17. (转)C# Oracle数据库操作类
  18. 2019.01.23 hdu1693 Eat the Trees(轮廓线dp)
  19. hdu 4432 第37届ACM/ICPC天津现场赛B题
  20. session过期跳出irame

热门文章

  1. Docker | 部署nginx服务
  2. SpringBoot(一) - SpringBoot 初识
  3. 面试突击91:MD5 加密安全吗?
  4. vue+spirngboot 分离技术实现图书信息的增删改查(改造这学期的课程设计【1】)
  5. 知识图谱-生物信息学-医学论文(Chip-2022)-BCKG-基于临床指南的中国乳腺癌知识图谱的构建与应用
  6. JavaScript基础复盘补缺
  7. Windows7下驱动开发与调试体系构建——0.概述
  8. mybatis-特殊查询
  9. 快速创建软件安装包-ClickOnce
  10. JS常见问题总结