递归组件

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

Tree.vue

  1. <template>
  2. <div class="tree">
  3. <div v-for="(item, index) in data" :key="item.name">
  4. 每一层 {{ item.name }}
  5. <Tree v-if="item?.children?.length" :data='item.children' />
  6. </div>
  7. </div>
  8. </template>
  9. <script setup lang="ts">
  10. //递归的第一种方式 直接引入自己
  11. import Tree from './Tree.vue'
  12. import { TreeList } from '../ts/type'
  13. type Props = {
  14. data?: TreeList[]
  15. }
  16. defineProps<Props>();
  17. </script>
  18. <style scoped>
  19. .tree {
  20. margin-left: 20px;
  21. border-left: 2px #01847f dashed;
  22. }
  23. </style>

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

  1. <template>
  2. <div>
  3. <Tree :data='data'/>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import Tree from './components/Tree.vue'
  8. import { reactive } from 'vue'
  9. import {TreeList } from './ts/type'
  10. const data = reactive<TreeList[]>([
  11. {
  12. name: 'no.1',
  13. children: [
  14. {
  15. name: 'no.1-1',
  16. children: [
  17. {
  18. name: 'no.1-1-1',
  19. children:[]
  20. }
  21. ]
  22. },
  23. ],
  24. }, {
  25. name:'no.2'
  26. }, {
  27. name: 'no.3',
  28. children: [{
  29. name:'no.3-1'
  30. }]
  31. }
  32. ])
  33. </script>
  34. <style scoped></style>

type.ts 属性数据的结构

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

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

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

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

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

  1. <template>
  2. <div class="tree">
  3. <div v-for="(item, index) in data" :key="item.name">
  4. 每一层 {{ item.name }}
  5. <Tree v-if="item?.children?.length" :data='item.children' />
  6. </div>
  7. </div>
  8. </template>
  9. <script setup lang="ts">
  10. import { TreeList } from '../ts/type'
  11. type Props = {
  12. data?: TreeList[]
  13. }
  14. defineProps<Props>();
  15. </script>
  16. <!--
  17. 第二种方式 就是像vue2 一样 export一个name出去
  18. 但是setup 语法糖下没办法使用 export
  19. 我们只需要再定义一个script标签就可以了
  20. -->
  21. <script lang="ts">
  22. export default {
  23. name:'Tree'
  24. }
  25. </script>
  26. <style scoped>
  27. .tree {
  28. margin-left: 20px;
  29. border-left: 2px #01847f dashed;
  30. }
  31. </style>

效果图

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

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

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

Tree.vue

  1. <template>
  2. <div class="tree">
  3. <div @click.stop="clickTreeItem(item)" v-for="(item, index) in data" :key="item.name">
  4. 每一层 {{ item.name }}
  5. <Tree @get-tree-item="clickTreeItem" v-if="item?.children?.length" :data='item.children' />
  6. <!-- Tree 组件不添加这个自定义事件的话 那么就只有最外层的根节点会向外传递数据 -->
  7. <!-- 注意此处派发的函数clickTreeItem没有传item参数了如果传了就相当于给树形组件(递归组件)的上级派发信息 没办法从外部拿到子节点所传递的数据了 -->
  8. <!-- @get-tree-item="clickTreeItem(item)" 写成这种形式的话 递归组件会依次向上层传递事件 -->
  9. <!-- 不传item的执行结果如下 -->
  10. <!--子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
  11. 子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
  12. 子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
  13. 父组件得到的item Proxy {name: 'no.1-1-1', children: Array(0)} -->
  14. <!-- 传item的执行的结果如下 -->
  15. <!-- 子组件派发的item Proxy {name: 'no.1-1-1', children: Array(0)}
  16. 子组件派发的item Proxy {name: 'no.1-1', children: Array(1)}
  17. 子组件派发的item Proxy {name: 'no.1', children: Array(1)}
  18. 父组件得到的item Proxy {name: 'no.1', children: Array(1)} -->
  19. </div>
  20. </div>
  21. </template>
  22. <script setup lang="ts">
  23. import { TreeList } from '../ts/type'
  24. type Props = {
  25. data?: TreeList[]
  26. }
  27. defineProps<Props>();
  28. const emit = defineEmits(['getTreeItem'])
  29. const clickTreeItem=(item:TreeList)=>{
  30. console.log('子组件派发的item', item)
  31. emit('getTreeItem',item)
  32. }
  33. </script>
  34. <!--
  35. 第二种方式 就是像vue2 一样 export一个name出去
  36. 但是setup 语法糖下没办法使用 export
  37. 我们只需要再定义一个script标签就可以了
  38. -->
  39. <script lang="ts">
  40. export default {
  41. name:'Tree'
  42. }
  43. </script>
  44. <style scoped>
  45. .tree {
  46. margin-left: 20px;
  47. border-left: 2px #01847f dashed;
  48. }
  49. </style>

App.vue

  1. <template>
  2. <div>
  3. <Tree :data='data' @get-tree-item="getTreeItem"/>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import Tree from './components/Tree.vue'
  8. import { reactive } from 'vue'
  9. import {TreeList } from './ts/type'
  10. const data = reactive<TreeList[]>([
  11. {
  12. name: 'no.1',
  13. children: [
  14. {
  15. name: 'no.1-1',
  16. children: [
  17. {
  18. name: 'no.1-1-1',
  19. children:[]
  20. }
  21. ]
  22. },
  23. ],
  24. }, {
  25. name:'no.2'
  26. }, {
  27. name: 'no.3',
  28. children: [{
  29. name:'no.3-1'
  30. }]
  31. }
  32. ])
  33. const getTreeItem = (item:TreeList) => {
  34. console.log('父组件得到的item',item)
  35. }
  36. </script>
  37. <style scoped></style>

vue3 递归组件 树形组件的更多相关文章

  1. vue2 递归组件--树形

    递归组件,官方给的教程太简便了,根本看不出到底怎么用.于是自己查网摸索了一下,这儿只把核心思想写出来. 效果如下图,点击后打开二级菜单,再点击后打开三级. //js //引子//思想:当v-if='f ...

  2. JS组件系列——分享自己封装的Bootstrap树形组件:jqTree

    前言:之前的一篇介绍了下如何封装自己的组件,这篇再次来体验下自己封装组件的乐趣.看过博主博客的园友应该记得之前分享过一篇树形菜单的使用JS组件系列——Bootstrap 树控件使用经验分享,这篇里面第 ...

  3. LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据

    LayUi框架中树形组件tree官方还在持续完善中,目前最新版本为v2.5.5 官方树形组件目前还不支持懒加载方式,之前我修改一版是通过reload重载实例方法填充子节点数据方式,因为递归页面元素时存 ...

  4. 转:vue+element实现树形组件

    项目中需要用到树形组件,在网上发现一个用vue+element实现的树形组件,现在记录下: demo地址:https://github.com/wilsonIs/vue-treeSelect

  5. element-ui tree树形组件自定义实现可展开选择表格

    最近做项目遇到一个需求,表格里可以展开,可以选择,大概效果如下图: 一开始是在table组件里找方法,使用了表格的合并方法,效果是实现了,但是表格的多选每次触发时,都会执行好几次,而且没法实现一部分的 ...

  6. element中的树形组件,如何获取父级菜单的id

    一般多选的树形组件,使用getCheckedNodes()方法只能获取到本级的菜单id,只有在子菜单全部选中的情况下才会选中上级.但我们想要不全选中子级的情况下也要获取它的上级,甚至上上级等,怎么办呢 ...

  7. iview实战 : 树形组件自定义

    Tree树形组件是 iview 中相对复杂的一个组件. 自定义节点内容 使用强大的 Render 函数可以自定义节点显示内容和交互,比如添加图标,按钮等. ——官方文档 但官方的 example 只有 ...

  8. vue3 + vite实现异步组件和路由懒加载

    在 Vue2 中,异步组件和路由懒加载处理使用 import 就可以很轻松实现.但是在Vue 3.x 中异步组件的使用与 Vue 2.x 完全不同了.本文就详细讲讲vue3中异步组件和路由懒加载的实现 ...

  9. Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo

    前两篇文章分享了基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通 ...

  10. 08 - Vue3 UI Framework - Input 组件

    接下来再做一个常用的组件 - input 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 input 组件有两种类型,即 input 和 textarea 类型 当类型为 ...

随机推荐

  1. 洛谷P1962 斐波那契数列 (矩阵快速幂)

    学了矩阵,练一下手... 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7; 4 using n ...

  2. 洛谷P2517 HAOI2010 订货 (费用流)

    标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...

  3. 项目管理构建工具——Maven(高阶篇)

    项目管理构建工具--Maven(高阶篇) 我们在之前的文章中已经基本了解了Maven,但也仅仅只止步于了解 Maven作为我们项目管理构建的常用工具,具备许多功能,在这篇文章中我们来仔细介绍 分模块开 ...

  4. SpringBoot (四) - 整合Mybatis,逆向工程,JPA

    1.SpringBoot整合MyBatis 1.1 application.yml # 数据源配置 spring: datasource: driver-class-name: com.mysql.c ...

  5. Resilience4J通过yml设置circuitBreaker

    介绍 Resilience4j是一个轻量级.易于使用的容错库,其灵感来自Netflix Hystrix,但专为Java 8和函数式编程设计. springcloud2020升级以后Hystrix被官方 ...

  6. 通过齐博fun函数实现调用每周赚取的积分排行使用

    下面代码保存到fun函数目录即可 <?php namespace app\common\fun; use think\db; class Jfrank { /** * @param string ...

  7. 函数柯里化实现sum函数

    需求 实现sum函数,使其可以传入不定长参数,以及不定次数调用 //示例 console.log(sum(1,2)(3)()) //6 console.log(sum(2,3,4,5)(1,2)(3) ...

  8. 闻道Go语言,6月龄必知必会

    大家好,我是马甲哥, 学习新知识, 我的策略是模仿-->归纳--->举一反三, 在同程倒腾Go语言一年有余,本次记录<闻道Go语言,6月龄必知必会>,形式是同我的主力语言C#做 ...

  9. element-ui el-table 多选和行内选中

    <template> <div style="width: 100%;height: 100%;padding-right: 10px"> <el-t ...

  10. Debian安装 WineHQ 安装包

    https://wiki.winehq.org/Debian_zhcn WineHQ 源仓库的密钥于 2018-12-19 改变过.如果您在此之前下载添加过该密钥,您需要重新下载和添加新的密钥并运行 ...