文档章节

Vue递归组件

羽阁丶
 羽阁丶
发布于 2017/08/18 09:26
字数 595
阅读 174
收藏 1

开始

在js/jsx中,我们可以通过递归的方式来生成一些有规律的dom结构,那么,在Vue模板中,我们能不能递归生成dom呢?答案是肯定的。在Vue中,组件可以递归的调用自己本身,但是有一些条件:

  1. 该组件要有name属性
  2. 要确保递归的调用有终止条件,防止内存溢出

Demo

下面为了方便理解递归组件,我写了一个小的demo:

有这么一份数据,我们希望能把它做成像文件树一样的结果

[
    {
        'name': 'Vue',
        'children': [
            {
                'name': '模板语法'
            },
            {
                'name': '计算属性'
            },
            {
                'name': '生命周期',
                'children': [
                    {
                        'name': 'beforeCreate'
                    },
                    {
                        'name': 'created'
                    },
                    {
                        'name': 'beforeMount'
                    },
                    {
                        'name': 'mounted'
                    },
                    {
                        'name': 'beforeUpdate'
                    },
                    {
                        'name': 'updated'
                    },
                    {
                        'name': 'beforeDestroy'
                    },
                    {
                        'name': 'destroyed'
                    }
                ]
            }
        ]
    },
    {
        'name': 'React',
        'children': [
            {
                'name': 'jsx'
            },
            {
                'name': '生命周期'
            }
        ]
    },
    {
        'name': 'Angular'
    }
]

先写我们的树组件Tree.vue

<template>
    <li>
        <span @click="toggle">
            <i v-if="hasChild" class="icon" :class="[open ? 'folder-open': 'folder']"></i>
            <i v-if="!hasChild" class="icon file-text"></i>
            {{ data.name }}
        </span>
        <ul v-show="open" v-if="hasChild">
            <tree-menu v-for="(item, index) in data.children" :data="item" :key="index"></tree-menu>
        </ul>
    </li>
</template>
 
<script>
export default {
    name: 'TreeMenu',
    props: {
        data: {
            type: Object,
            required: true
        }
    },
    data() {
        return {
            open: false
        }
    },
    computed: {
        hasChild() {
            return this.data.children && this.data.children.length
        }
    },
    methods: {
        toggle() {
            if(this.hasChild) {
                this.open = !this.open
            }
        }
    }
}
</script>
 
<style>
ul {
    list-style: none;
    margin: 10px 0;
}
li {
    padding: 3px 0;
}
li > span {
    cursor: pointer;
    font-size: 14px;
    line-height: 20px;
}
i.icon {
    display: inline-block;
    width: 20px;
    height: 20px;
    margin-right: 5px;
    background-repeat: no-repeat;
    vertical-align: middle;
}
.icon.folder {
    background-image: url("../assets/images/folder.svg");
}
.icon.folder-open {
    background-image: url("../assets/images/folder-open.svg");
}
.icon.file-text {
    background-image: url("../assets/images/file.svg");
}
.tree-menu li {
    line-height: 1.5;
}
</style>

可以看到,我们在Tree组件中有个name选项,值为TreeMenu,然后组件内部调用TreeMenu本身,通过v-for来进行递归条件的判断,这就形成了一个递归组件

然后我们在外部App.vue调用Tree组件

<template>
    <div class="tree-menu">
        <ul v-for="item in data">
            <my-tree :data="item"></my-tree>
        </ul>
    </div>
</template>
 
<script>
var myData = [
    {
        'name': 'Vue',
        'children': [{
                'name': '模板语法'
            },
            {
                'name': '计算属性'
            },
            {
                'name': '生命周期',
                'children': [
                    {
                        'name': 'beforeCreate'
                    },
                    {
                        'name': 'created'
                    },
                    {
                        'name': 'beforeMount'
                    },
                    {
                        'name': 'mounted'
                    },
                    {
                        'name': 'beforeUpdate'
                    },
                    {
                        'name': 'updated'
                    },
                    {
                        'name': 'beforeDestroy'
                    },
                    {
                        'name': 'destroyed'
                    }
                ]
            }
        ]
    },
    {
        'name': 'React',
        'children': [{
                'name': 'jsx'
            },
            {
                'name': '生命周期',
                'children': []
            }
        ]
    },
    {
        'name': 'Angular'
    }
];

 
import MyTree from './components/Tree'
export default {
    components: {
        MyTree
    },
    data() {
        return {
            data: myData
        }
    }
}
</script>

最终效果如图:

效果图

结束

虽然这篇博客看起来很简单,只是一个小的知识点,但是Vue的递归组件确实是一个非常强大的功能。可以用来实现一些类似文件树、部门树、级联选择这样的组件,在实际业务开发中这些组件也经常用到,还是非常重要的~

原文地址:http://blog.yuantang.site/2017/08/17/Vue递归组件

© 著作权归作者所有

下一篇: Vue配置jsx
羽阁丶
粉丝 1
博文 14
码字总数 9436
作品 0
杭州
前端工程师
私信 提问
没有废话的vue高级进阶( 三 ) 组件高级用法及最佳实践

书接上回,上篇介绍了vue组件通信比较有代表性的几种方法,本篇主要讲述一下组件的高级用法和最佳实践,争取用最少的篇幅占领高地!(多说一句,后续这个系列会有,我总有办法能让大家看懂,...

张不怂
05/09
0
0
Vue中你不知道但却很实用的黑科技

本文纯技术干货,首发于 掘金,转载请注明出处和作者。 最近数月一直投身于 iView 的开源工作中,完成了大大小小 30 多个 UI 组件,在 Vue 组件化开发中积累了不少经验。其中也有很多带有技巧...

Aresn
2018/10/29
0
0
Vue倔强青铜-入门和组件化通信G

入门 作为前端最容易上手的框架,Vue入门其实没啥说的,我放一段清单的代码,大家能看懂就说明能上手了 大概包含的内容如下,对这个例子熟悉后,才是我们的正文,如果上面代码有没看懂的地方...

蜗牛老湿
03/17
0
0
一本让你醍醐灌顶的小册:《Vue.js组件精讲》

三年前,我开始接触 Vue.js 框架,当时就被它的轻量、组件化和友好的 API 所吸引。与此同时,我也开源了 iView 项目。三年的磨(cǎi )砺(kēng),沉淀了不少关于 Vue.js 组件的经验,于是乎,...

Aresn
2018/12/20
0
0
前端面试:专注Vue.js常见的问题答疑,掌握了基本上Vue就过关了

v-show 与 v-if 区别 第一题应该是最简单的,提这个问题,也是想让候选人不那么紧张,因为但凡用过 Vue.js,多少知道 v-show 和 v-if 的区别,否则就没得聊了。不过这最简单的一道题,有三个...

大灰狼的小绵羊哥哥
04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Angular 英雄编辑器

应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。 创建英雄组件 使用 Angular CLI 创建一个名为 heroes 的新组件。 ng gener...

honeymoose
今天
5
0
Kernel DMA

为什么会有DMA(直接内存访问)?我们知道通常情况下,内存数据跟外设之间的通信是通过cpu来传递的。cpu运行io指令将数据从内存拷贝到外设的io端口,或者从外设的io端口拷贝到内存。由于外设...

yepanl
今天
6
0
hive

一、hive的定义: Hive是一个SQL解析引擎,将SQL语句转译成MR Job,然后再在Hadoop平台上运行,达到快速开发的目的 Hive中的表是纯逻辑表,就只是表的定义,即表的元数据。本质就是Hadoop的目...

霉男纸
今天
3
0
二、Spring Cloud—Eureka(Greenwich.SR1)

注:本系列文章所用工具及版本如下:开发工具(IDEA 2018.3.5),Spring Boot(2.1.3.RELEASE),Spring Cloud(Greenwich.SR1),Maven(3.6.0),JDK(1.8) Eureka: Eureka是Netflix开发...

倪伟伟
昨天
13
0
eclipse常用插件

amaterasUML https://takezoe.github.io/amateras-update-site/ https://github.com/takezoe/amateras-modeler modelGoon https://www.cnblogs.com/aademeng/articles/6890266.html......

大头鬼_yc
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部