前言
在之前一篇《Vue 中使用渲染函数 render 实现无限节点的树》中我们介绍了如何使用 render
函数中的 h
函数来实现无限节点树的渲染,但这种方式有很多小伙伴们可能使用起来不是很习惯。有没有一种更加直观的方式来实现呢?其实是有的,就是我们可以递归调用树节点组件自身实现无限节点的树。
这种方式跟使用 jsx 可以轻松使用递归实现有点类似。废话不多数,先上在线 Demo,Github 上源码地址
代码分析
树节点组件 TreeNode.vue
代码如下:
<template> <li> <a :class="{'open': isOpen && data.children.length > 0, 'close': !isOpen && data.children.length > 0}" href="javascript:void(0);" class="name" @click="isOpen = !isOpen" >{{ data.name }}</a> <ul :class="{'hide': !isOpen}"> <tree-node v-for="item in data.children" :key="item.id" :data="item" /> </ul> </li> </template> <script> export default { name: 'TreeNode', props: { data: { type: Object, default: () => { return { id: String(new Date().getTime() + Math.floor(9999 * Math.random())), name: '', children: [] } } } }, data () { return { isOpen: false } } } </script>
生成树页面 TreeDemoII.vue
代码如下:
<template> <article class="pageview"> <header class="header fixed"> <div class="container"> <a class="back back_ico" href="javascript:void(0);" @click="goBack" ></a><span class="title">{{ msg }}</span> </div> </header> <section class="main"> <div id="menu" class="clearfix menu" > <ul> <tree-node v-for="item in data" :key="item.id" :data="item" /> </ul> </div> </section> </article> </template> <script> import TreeNode from '../components/TreeNode' import { goBack } from '../util/tools' export default { name: 'TreeDemoII', components: { TreeNode }, data () { return { msg: 'Tree Demo II', data: [ { id: 0, name: '节点1', children: [ { id: 1, name: '节点1-1', children: [] }, { id: 2, name: '节点1-2', children: [ { id: 7, name: '节点1-2-1', children: [ { id: 10, name: '节点1-2-1-1', children: [] }, { id: 11, name: '节点1-2-1-2', children: [] } ] }, { id: 8, name: '节点1-2-2', children: [] } ] } ] }, { id: 3, name: '节点2', children: [ { id: 4, name: '节点2-1', children: [] }, { id: 5, name: '节点2-2', children: [] } ] }, { id: 6, name: '节点3', children: [] } ] } }, methods: { goBack: goBack }, } </script> <style lang="scss" scoped> .menu { /deep/ { .hide { display: none !important; } a { color: #000; padding: 10px 0; display: block; } ul { padding-left: 0px; } li { list-style: none; margin-left: 30px; border-left: 1px dashed #000; .name:before { content: "--"; } .close:after { content: "[+]"; margin-left: 10px; } .open:after { content: "[-]"; margin-left: 10px; } } } } </style>
总结
这里主要是使用递归调用的思想来实现树节点,Vue 组件是支持在本组件中调用本组件的,这非常有趣,让我们可以更加灵活的实现一些特定场景的功能,比如树、无限菜单等。