赞
踩
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[] | [] //子节点 可有可无 还可能传空数组
- }
第二种方式 就是像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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。