vue tree组件的实现

本文介绍了如何在Vue中实现递归组件来创建树形结构。通过组件内递归调用来处理任意层级的数据,并强调了递归组件需包含name属性以正确调用自身。在实现过程中,遇到的问题包括因层级过深导致的index值丢失,解决方案是在初始化数据时添加父级引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归组件

一个简单的递归组件如下例所示:

tree.vue

<template>
    <ul class="child-node">
        <li class="vue-tree-item" v-for="(item, index) in treeDataList" :key="index">
            <div class="tree-node"
                :style="pLeft" @click="toggleChildren(item)">
               {{item.name}}
            </div>
            <exportTree
                v-if="item.children"
                :tree-data-list="item.children"
                :tree-index="treeIndex + 1"
                @toggleChildren="toggleChildren">
            </exportTree>
        </li>
    </ul>
</template>
<script>
    export default {
        name: 'exportTree',
        props: {
            treeDataList: {
                type: Array,
                default: []
            },
            treeIndex: {
                type: Number,
                default: 0
            }
        },
        data () {
            return {
                pLeft: `padding-left:${15 * (this.treeIndex + 1)}px;`
            }
        },
        methods: {
            toggleChildren (item) {
                this.$emit('toggleChildren', item)
            }
        }
    }
</script>

index.vue

<template>
    <div class="module-content-wrapper" style="width: 200px;border: 1px solid #ccc;">
        <exportTree
            :tree-data-list="treeDataList"
            @toggleChildren="toggleChildren">
        </exportTree>
    </div>
</template>
<script>
    import exportTree from 'components/exportTree/exportTree'
    export default {
        components: {
            exportTree
        },
        data () {
            return {
                treeDataList: [
                    {
                        "id": 1,
                        "name": "总公司",
                        "order": 1,
                        "parent": null,
                        "children": [
                             {
                                "id": 2,
                                "name": "研发部门1",
                                "parent": 1,
                                "order": 1,
                                "has_children": false
                            },
                            {
                                "id": 3,
                                "name": "jx",
                                "parent": 1,
                                "order": 2,
                                "has_children": false
                            }
                        ]
                    }
                ]
            }
        },
        methods: {
            toggleChildren (item) {
                console.log(item)
            }
        }
    }
</script>

总结:

  1. 组件内调用组件,本来就是一种递归的思想。绑定的treeDataList有多少层级,那就会递归多少层,因为每一层都有v-for都会循环子节点。
  2. 注意:组件内调用组件,需要有一个条件来终止递归
  3. 递归组件必须含有name这个属性(name指的是组件的名字),因为没有name这个属性会造成空间自身不能调用自身

遇到的问题:

tree组件有菜单功能:上移、下移。 因为层级太深,会导致真正的index值丢失
解决:
在初始化递归处理数据时,添加对应的引用父级(即直接父级)

this.treeDataList.forEach(item => {
    this.addParent(item, this.treeDataList)
})

function addParent (tree, directParent) {
   /**
     * tree : 当前的节点 {}
     * parent: 当前节点的父级[]
     */
    tree.directParent = directParent
   
    if (tree.children == null) {
        return
    }
    tree.children.forEach(item => {
        this.addParent(item, tree)
    })
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值