vue组件递归——级联菜单的实现

最近做项目经常会用到一些UI库,比如elementiview等,这些能够快速构建应用的库真的十分方便。比如iview的级联菜单很是好用,但是在使用的同时不免起了一些疑惑,它是怎么做到多级联动,依我所知,如果一个数据是多层的,我们就要多次使用v-for,并且需要知道要循环几次,但是这个组件貌似不需要多次复用。好啦,下面进入正题!

数据

首先我们手里是一份这样的JSON数据:

list: [
{
    "id": "1",
    "menuName": "项目管理",
    "childTree": [{
        "menuName": "项目进度",
        "childTree": [{
            "menuName": "项目一",
            "childTree": [{ "menuName": "详细信息" }]
        }]
    }, {
        "menuName": "任务安排"
    }]
}, 
{
    "id": "2",
    "menuName": "数据统计"
}, 
{
    "id": "3",
    "menuName": "人员管理"
}]

子组件递归

这是最重要的环节,组件的递归实现了级联菜单的多级联动,这个过程就如同实现对象的深复制一样。那么接下来我们按照这份数据写一个递归组件:

// 子组件代码
<template>
    <li>
        <span @click="toggle">
            {{ model.menuName }}
        </span>
        <ul v-if="isFolder" v-show="open">
            <items v-for="(item, index) in model.childTree" :model="item" :key="index"></items>
        </ul>
    </li>
</template>

<script type="text/javascript">
    export default {
        // 组件递归必要条件,name属性
        name: 'items',
        props: ['model'],
        data() {
            return {
                // 控制子列表的显示隐藏
                open: false
            }
        },
        computed: {
            // 是否还有子列表需要渲染,作为v-if的判断条件
            isFolder() {
                return this.model.childTree && this.model.childTree.length
            }
        },
        methods: {
            // 切换列表显示隐藏的方法
            toggle() {
                if(this.isFolder) {
                    this.open = !this.open
                }
            },
        }
    }
</script>

这里要强调以下,组件的name属性必须要有,否则无法实现递归,当然递归也需要有终止的条件,上边的isFloder便是了。

父组件调用

<template>
    <div>
        <ul>
            <items v-for="(model, index) in list" :model="model" :key="index"></items>
        </ul>
    </div>
</template>

<script type="text/javascript">
    components: {
        Items
    },
    data() {
        return {
            list: ...
        }
    }
</script>

这里也有需要注意的,v-for循环需要绑定key,否则会报警告。
最后来看下这个简单级联菜单的效果:

级联列表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,967评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,420评论 25 708
  • 惯例早起,洗漱后坐在桌前准备化妆。手上还是熟悉的步骤,眼镜看着镜子,突然想起要给自己说说话。 “对不起”,三个字说...
    萌巾阅读 199评论 0 0
  • 京港澳高速新乡段发生重大事故,受伤的有盛源的父母,让人揪心。 河南省公安厅高速交警总队官方微博@河南高速公安通报称...
    郭晓闻阅读 573评论 4 4