【Vue2】利用组件递归方式实现目录树组件

前言

        看到最近一些公司前端笔试题,发现他们都很喜欢考察递归。这使我不得不想到在前端开发中,也会遇到的一些需要利用递归思想实现的一些场景,如目录树组件,大多数前端开发经常参与流水型业务,对组件递归的场景用之较少。以下为作者根据实践,分享递归组件实现目录树的设计思路以及实现方式。我们要实现一个目录组件,效果如下。

设计思路

        在真实业务中,treeList是后端返回的,可能有数十个层级。这里为了方便我模拟了三层数据,旨在清晰逻辑,数据以及结构如下:

treeList: [
    {
        id: 1,
        name: '一级1',
        children: [
            {
                id: 2,
                name: '二级1',
                children: [
                    {
                        id: 3,
                        name: '三级1'
                    },
                    {
                        id: 4,
                        name: '三级2'
                    }
                ]
            },
            {
                id: 5,
                name: '二级2'
            }
        ]
    },
    {
        id: 6,
        name: '一级2',
        children: [
            {
                id: 7,
                name: '二级3'
            }
        ]
    }
]

        从数据结构中可以发现,外层为一个数组,每一项有id作为唯一标识,name作为展示数据,children为子数组,包含类似外层的结构。抽象成“树”的形式如下图。

         根据上图基本图形化数据结构,若要实现点击选中的效果需要设计数据流。

  • 初始化时,将activeKey传入Tree组件,通过层层传递到各个子组件,使用动态class的方式用逻辑item.id === activeKey判断是否为选中状态。
  • 选中某一个节点,则触发change事件,层层往上抛,最终在调用者处理activeKey的赋值逻辑形成闭环。

        这里为什么不在数据中注入selected标识来标记是否选中?有以下几点:

  • 注入selected标识会对源数据造成风险,如果selected被定义在接口返回值中,则会对源数据进行污染。
  • 注入selected会增加逻辑复杂度,增加维护成本;因为选中后,不仅是修改当前元素的selected,还要遍历整个list,将selected初始化为false后方可修改。

        经过以上设计,我们大致可以得出组件调用的逻辑图。

实现过程

        我们需要创建两个组件,一个调用者TreeTest组件,另一个为树组件Tree。通过TreeTest去调用Tree,Tree内部递归。

         对于TreeTest组件,我们希望他是一个Tree组件的调用者,同时也是选中态的“数据中心”。

<Tree :list="treeList" :activeKey="activeKey" @change="handleChange"/>

        对于Tree组件,我们希望将递归逻辑全部在Tree组件内部实现,与外部的数据和逻辑解耦,从而提高代码的可维护性。(Tree内部调用自身不用import自己,而使用name属性与标签中Tree保持一致即可)

<div class="tree">
    <div v-for="item in list" :key="item.id">
        <div class="name" :class="{ 'active': activeKey === item.id }" @click="changeItem(item)">{{ item.name }}</div>
        <Tree :list="item.children" :activeKey="activeKey" v-if="item.children" @change="changeItem"/>
    </div>
</div>

总结

        到这里我们基本实现了用组件递归的方式去开发目录树组件,代码非常简单,不过思想值得关注。希望能够用本篇博客给正在的浏览的您一些灵感,如果对您有帮助可以点点关注哦,如果有好的建议或者意见可以评论或者私信,感谢您的支持!

        PS:相关代码已绑定本文资源,可以免费下载,希望对您有帮助。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

划雨悦潭之赋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值