快速实现一个简单可复用可扩展的Vue树组件
一、树形数据结构
[
{
id: '1',
title: '节点1'
children: [
{
id: '1-1',
title: '节点1-1'
},
{
id: '1-2',
title: '节点1-2'
}
]
},
{
id: '2',
title: '节点2',
children: [
{
id: '2-1',
title: '节点2-1'
},
{
id: '2-2',
title: '节点2-2'
}
]
},
{
id: '3',
title: '节点3'
}
]
二、Vue树组件实现的两个重要属性
1、组件的name属性
允许组件模板递归地调用自身。注意,组件在全局用 Vue.component() 注册时,全局 ID 自动作为组件的 name。
指定 name 选项的另一个好处是便于调试。有名字的组件有更友好的警告信息。另外,当在有 vue-devtools,未命名组件将显示成
,这很没有语义。通过提供 name 选项,可以获得更有语义信息的组件树。
2、插槽
Vue插槽借鉴于Web components,是在父组件自定义实现子组件部分dom的一个方法,这大大提高了子组件的复用性和扩展性。
下面是一个简单的插槽使用例子。
子组件:
子组件
父组件通过插槽插入的内容——具名插槽
父组件通过默认插槽插入的内容——默认插槽
1)、作用域插槽
子组件:
子组件
子组件传到插槽的nodeData的title:{{ someProp.nodeData.title }}
2)、插槽函数
三、树组件渲染的实现
1、树组件调用形式
作为一个可复用的树节点,渲染出来的树结构应该是可以自定义的,同时对于传入组件的prop尽可能简单。
这里设计的prop仅传入一个树形数据treeData,对于每一个节点,使用作用域插槽提供每一个节点的数据来调用者自定义渲染。所以组件调用形式很简单:
{{ nodeData.title }}
2、树组件代码实现
树节点渲染组件,该组件通过归调用自身渲染一个子树,一直递归到渲染完全部叶子节点。
供外部调用的树形组件,提供一些外部调用的接口
class="tree-node-children"
:style="{
paddingLeft: indent
}"
v-if="nextShow">
v-for="(child, idx) of nodeData.children"
:nodeData="child"
:indent="indent"
:key="idx">
v-for="(nodeData, idx) of treeData"
:nodeData="nodeData"
:key="idx">
.tree-container
text-align left
树组件的componentMap保存了所有后代组件的引用。这样好处在于:在使用tree组件的时候,我们直接访问的只有树组件,想直接调用叶子节点的相关方法,可以通过树组件做转发。比如想让id为1的节点折叠起后代元素,可以调用this.$refs.tree.showChildren(1, true),在树组件的showChildren函数内,取出对应的节点组件,调用节点组件的方法。
节点自身内容的渲染。节点组件的tree树形保存了树组件的引用,节点自身内容的渲染,使用了一个子组件node-content。而node-content的内容,来自于树组件的插槽,我们通过前面所描述函数形式访问到树组件的插槽,调用函数得到了虚拟DOM,作为组件node-content的内容。当然如果未提供插槽,node-content的内容会是一段提醒含义的html串,提醒使用者插入插槽(你也可以修改为一个默认的渲染,比如渲染出nodeData.title)。
在提供的作用域插槽中,node-content组件向该插槽传递了parentData(上级节点数据), data(本级节点数据), level(层级)等一些可能常用的属性。
评论