1. Tree树形控件
1.1. Tree树形控件用清晰的层级结构展示信息, 可展开或折叠。
1.2. Tree树形控件内部使用了Node类型的对象来包装用户传入的数据, 用来保存目前节点的状态。
1.3. Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
data | 展示数据 | array | 无 | 无 |
empty-text | 内容为空的时候展示的文本 | String | 无 | 无 |
node-key | 每个树节点用来作为唯一标识的属性, 整棵树应该是唯一的 | String | 无 | 无 |
props | 配置选项, 具体看下表 | object | 无 | |
render-after-expand | 是否在第一次展开某个树节点后才渲染其子节点 | boolean | 无 | true |
load | 加载子树数据的方法, 仅当lazy属性为true时生效 | function(node, resolve) | 无 | 无 |
render-content | 树节点的内容区的渲染Function | Function(h, { node, data, store } | 无 | 无 |
highlight-current | 是否高亮当前选中节点, 默认值是false。 | boolean | 无 | false |
default-expand-all | 是否默认展开所有节点 | boolean | 无 | false |
expand-on-click-node | 是否在点击节点的时候展开或者收缩节点, 默认值为true, 如果为false, 则只有点箭头图标的时候才会展开或者收缩节点。 | boolean | 无 | true |
check-on-click-node | 是否在点击节点的时候选中节点, 默认值为false, 即只有在点击复选框时才会选中节点。 | boolean | 无 | false |
auto-expand-parent | 展开子节点的时候是否自动展开父节点 | boolean | 无 | true |
default-expanded-keys | 默认展开的节点的key的数组 | array | 无 | 无 |
show-checkbox | 节点是否可被选择 | boolean | 无 | false |
check-strictly | 在显示复选框的情况下, 是否严格的遵循父子不互相关联的做法, 默认为false | boolean | 无 | false |
default-checked-keys | 默认勾选的节点的key的数组 | array | 无 | 无 |
current-node-key | 当前选中的节点 | string, number | 无 | 无 |
filter-node-method | 对树节点进行筛选时执行的方法, 返回true表示这个节点可以显示, 返回false则表示这个节点会被隐藏 | Function(value, data, node) | 无 | 无 |
accordion | 是否每次只打开一个同级树节点展开 | boolean | 无 | false |
indent | 相邻级节点间的水平缩进, 单位为像素 | number | 无 | 16 |
icon-class | 自定义树节点的图标 | string | 无 | 无 |
lazy | 是否懒加载子节点, 需与load方法结合使用 | boolean | 无 | false |
draggable | 是否开启拖拽节点功能 | boolean | 无 | false |
allow-drag | 判断节点能否被拖拽 | Function(node) | 无 | 无 |
allow-drop | 拖拽时判定目标节点能否被放置。type参数有三种情况: 'prev'、'inner'和'next', 分别表示放置在目标节点前、插入至目标节点和放置在目标节点后 | Function(draggingNode, dropNode, type) | 无 | 无 |
1.4. props
参数 | 说明 | 类型 |
label | 指定节点标签为节点对象的某个属性值 | string, function(data, node) |
children | 指定子树为节点对象的某个属性值 | string |
disabled | 指定节点选择框是否禁用为节点对象的某个属性值 | boolean, function(data, node) |
isLeaf | 指定节点是否为叶子节点, 仅在指定了lazy属性的情况下生效 | boolean, function(data, node) |
1.5. 方法
方法名 | 说明 | 参数 |
filter | 对树节点进行筛选操作 | 接收一个任意类型的参数, 该参数会在filter-node-method中作为第一个参数 |
updateKeyChildren | 通过keys设置节点子元素, 使用此方法必须设置node-key属性 | (key, data)接收两个参数, 1.节点key 2.节点数据的数组 |
getCheckedNodes | 若节点可被选择(即show-checkbox为true), 则返回目前被选中的节点所组成的数组 | (leafOnly, includeHalfChecked)接收两个boolean类型的参数, 1.是否只是叶子节点, 默认值为false 2.是否包含半选节点, 默认值为false |
setCheckedNodes | 设置目前勾选的节点, 使用此方法必须设置node-key属性 | (nodes)接收勾选节点数据的数组 |
getCheckedKeys | 若节点可被选择(即show-checkbox为true), 则返回目前被选中的节点的key所组成的数组 | (leafOnly)接收一个boolean类型的参数, 若为true则仅返回被选中的叶子节点的keys, 默认值为false |
setCheckedKeys | 通过keys设置目前勾选的节点,使用此方法必须设置node-key属性 | (keys, leafOnly)接收两个参数, 1.勾选节点的key的数组 2.boolean类型的参数, 若为true则仅设置叶子节点的选中状态, 默认值为false |
setChecked | 通过key / data设置某个节点的勾选状态, 使用此方法必须设置node-key属性 | (key/data, checked, deep)接收三个参数, 1.勾选节点的key或者data 2.boolean 类型, 节点是否选中 3.boolean类型, 是否设置子节点, 默认为false |
getHalfCheckedNodes | 若节点可被选择(即show-checkbox为true), 则返回目前半选中的节点所组成的数组 | 无 |
getHalfCheckedKeys | 若节点可被选择(即show-checkbox为true), 则返回目前半选中的节点的key所组成的数组 | 无 |
getCurrentKey | 获取当前被选中节点的key, 使用此方法必须设置node-key属性, 若没有节点被选中则返回null | 无 |
getCurrentNode | 获取当前被选中节点的data, 若没有节点被选中则返回null | 无 |
setCurrentKey | 通过key设置某个节点的当前选中状态, 使用此方法必须设置node-key属性 | (key)待被选节点的key, 若为null则取消当前高亮的节点 |
setCurrentNode | 通过node设置某个节点的当前选中状态, 使用此方法必须设置node-key属性 | (node)待被选节点的node |
getNode | 根据data或者key拿到Tree组件中的node | (data)要获得node的key或者data |
remove | 删除Tree中的一个节点, 使用此方法必须设置node-key属性 | (data)要删除的节点的data或者node |
append | 为Tree中的一个节点追加一个子节点 | (data, parentNode)接收两个参数, 1.要追加的子节点的data 2.子节点的parent的data、key或者node |
insertBefore | 为Tree的一个节点的前面增加一个节点 | (data, refNode)接收两个参数, 1.要增加的节点的data 2.要增加的节点的后一个节点的data、key或者node |
insertAfter | 为Tree的一个节点的后面增加一个节点 | (data, refNode)接收两个参数, 1.要增加的节点的data 2.要增加的节点的前一个节点的data、key或者node |
1.6. Events
事件名 | 说明 | 回调参数 |
node-click | 节点被点击时的回调 | 共三个参数, 依次为: 传递给data属性的数组中该节点所对应的对象、节点对应的Node、节点组件本身。 |
node-contextmenu | 当某一节点被鼠标右键点击时会触发该事件 | 共四个参数, 依次为: event、传递给data属性的数组中该节点所对应的对象、节点对应的Node、节点组件本身。 |
check-change | 节点选中状态发生变化时的回调 | 共三个参数, 依次为: 传递给data属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点 |
check | 当复选框被点击的时候触发 | 共两个参数, 依次为: 传递给data属性的数组中该节点所对应的对象、树目前的选中状态对象, 包含checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys四个属性 |
current-change | 当前选中节点变化时触发的事件 | 共两个参数, 依次为: 当前节点的数据, 当前节点的Node对象 |
node-expand | 节点被展开时触发的事件 | 共三个参数, 依次为: 传递给data属性的数组中该节点所对应的对象、节点对应的Node、节点组件本身 |
node-collapse | 节点被关闭时触发的事件 | 共三个参数, 依次为: 传递给data属性的数组中该节点所对应的对象、节点对应的Node、节点组件本身 |
node-drag-start | 节点开始拖拽时触发的事件 | 共两个参数, 依次为: 被拖拽节点对应的Node、event |
node-drag-enter | 拖拽进入其他节点时触发的事件 | 共三个参数, 依次为: 被拖拽节点对应的Node、所进入节点对应的Node、event |
node-drag-leave | 拖拽离开某个节点时触发的事件 | 共三个参数, 依次为: 被拖拽节点对应的Node、所离开节点对应的Node、event |
node-drag-over | 在拖拽节点时触发的事件(类似浏览器的mouseover事件) | 共三个参数, 依次为: 被拖拽节点对应的Node、当前进入节点对应的Node、event |
node-drag-end | 拖拽结束时(可能未成功)触发的事件 | 共四个参数, 依次为: 被拖拽节点对应的Node、结束拖拽时最后进入的节点(可能为空)、被拖拽节点的放置位置(before、after、inner)、event |
node-drop | 拖拽结束时(可能未成功)触发的事件 | 共四个参数, 依次为: 被拖拽节点对应的Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置(before、after、inner)、event |
1.7. Scoped Slot
name | 说明 |
— | 自定义树节点的内容, 参数为 { node, data } |
2. Tree树形控件例子
2.1. 使用脚手架新建一个名为element-ui-tree的前端项目, 同时安装Element插件。
2.2. 编辑index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import BaseTree from '../components/BaseTree.vue'
import ShowCheckboxTree from '../components/ShowCheckboxTree.vue'
import DefaultExpandedCheckedKeysTree from '../components/DefaultExpandedCheckedKeysTree.vue'
import DisabledTree from '../components/DisabledTree.vue'
import NodeKeyTree from '../components/NodeKeyTree.vue'
import RenderContentScopedSlotTree from '../components/RenderContentScopedSlotTree.vue'
import FilterTree from '../components/FilterTree.vue'
import AccordionTree from '../components/AccordionTree.vue'
import DraggableTree from '../components/DraggableTree.vue'
Vue.use(VueRouter)
const routes = [
{ path: '/', redirect: '/BaseTree' },
{ path: '/BaseTree', component: BaseTree },
{ path: '/ShowCheckboxTree', component: ShowCheckboxTree },
{ path: '/DefaultExpandedCheckedKeysTree', component: DefaultExpandedCheckedKeysTree },
{ path: '/DisabledTree', component: DisabledTree },
{ path: '/NodeKeyTree', component: NodeKeyTree },
{ path: '/RenderContentScopedSlotTree', component: RenderContentScopedSlotTree },
{ path: '/FilterTree', component: FilterTree },
{ path: '/AccordionTree', component: AccordionTree },
{ path: '/DraggableTree', component: DraggableTree }
]
const router = new VueRouter({
routes
})
export default router
2.3. 在components下创建BaseTree.vue
<template>
<div>
<h1>基础用法</h1>
<h4>基础的树形结构展示。</h4>
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick (data) {
console.log(data)
}
}
}
</script>
2.4. 在components下创建ShowCheckboxTree.vue
<template>
<div>
<h1>可选择</h1>
<h4>适用于需要选择层级时使用。</h4>
<h4>由于在点击节点时才进行该层数据的获取, 默认情况下Tree无法预知某个节点是否为叶子节点, 所以会为每个节点添加一个下拉按钮, 如果节点没有下层数据, 则点击后下拉按钮会消失。同时, 你也可以提前告知Tree某个节点是否为叶子节点, 从而避免在叶子节点前渲染下拉按钮。</h4>
<el-tree :props="props" :load="loadNode" lazy show-checkbox @check-change="handleCheckChange"></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
props: {
label: 'name',
children: 'zones'
},
count: 1
}
},
methods: {
handleCheckChange (data, checked, indeterminate) {
console.log(data, checked, indeterminate)
},
loadNode (node, resolve) {
if (node.level === 0) {
return resolve([{ name: 'region1' }, { name: 'region2' }])
}
if (node.level > 3) return resolve([])
var hasChild
if (node.data.name === 'region1') {
hasChild = true
} else if (node.data.name === 'region2') {
hasChild = false
} else {
hasChild = Math.random() > 0.5
}
setTimeout(() => {
var data
if (hasChild) {
data = [{
name: 'zone' + this.count++
}, {
name: 'zone' + this.count++
}]
} else {
data = []
}
resolve(data)
}, 500)
}
}
}
</script>
2.5. 在components下创建DefaultExpandedCheckedKeysTree.vue
<template>
<div>
<h1>默认展开和默认选中-可将Tree的某些节点设置为默认展开或默认选中</h1>
<h4>分别通过default-expanded-keys和default-checked-keys设置默认展开和默认选中的节点。需要注意的是, 此时必须设置node-key, 其值为节点数据中的一个字段名, 该字段在整棵树中是唯一的。</h4>
<el-tree :data="data" show-checkbox node-key="id" :default-expanded-keys="[2, 3]" :default-checked-keys="[5]" :props="defaultProps"></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
2.6. 在components下创建DisabledTree.vue
<template>
<div>
<h1>禁用状态</h1>
<h4>通过disabled, 可将Tree的某些节点设置为禁用状态。</h4>
<el-tree :data="data" show-checkbox node-key="id" :default-expanded-keys="[2, 3]" :default-checked-keys="[5]"></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
id: 1,
label: '一级 2',
children: [{
id: 3,
label: '二级 2-1',
children: [{
id: 4,
label: '三级 3-1-1'
}, {
id: 5,
label: '三级 3-1-2',
disabled: true
}]
}, {
id: 2,
label: '二级 2-2',
disabled: true,
children: [{
id: 6,
label: '三级 3-2-1'
}, {
id: 7,
label: '三级 3-2-2',
disabled: true
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
2.7. 在components下创建NodeKeyTree.vue
<template>
<div>
<h1>树节点的选择</h1>
<h4>本例展示如何获取和设置选中节点。获取和设置各有两种方式: 通过node或通过key。如果需要通过key来获取或设置, 则必须设置node-key。</h4>
<el-tree :data="data" show-checkbox default-expand-all node-key="id" ref="tree" highlight-current :props="defaultProps"></el-tree>
<div class="buttons">
<el-button @click="getCheckedNodes">通过 node 获取</el-button>
<el-button @click="getCheckedKeys">通过 key 获取</el-button>
<el-button @click="setCheckedNodes">通过 node 设置</el-button>
<el-button @click="setCheckedKeys">通过 key 设置</el-button>
<el-button @click="resetChecked">清空</el-button>
</div>
</div>
</template>
<script>
export default {
methods: {
getCheckedNodes () {
console.log(this.$refs.tree.getCheckedNodes())
},
getCheckedKeys () {
console.log(this.$refs.tree.getCheckedKeys())
},
setCheckedNodes () {
this.$refs.tree.setCheckedNodes([{
id: 5,
label: '二级 2-1'
}, {
id: 9,
label: '三级 1-1-1'
}])
},
setCheckedKeys () {
this.$refs.tree.setCheckedKeys([3])
},
resetChecked () {
this.$refs.tree.setCheckedKeys([])
}
},
data () {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
2.8. 在components下创建RenderContentScopedSlotTree.vue
<template>
<div>
<h1>自定义节点内容</h1>
<h4>可以通过两种方法进行树节点内容的自定义: render-content和scoped slot。使用render-content指定渲染函数, 该函数返回需要的节点区内容即可。使用scoped slot会传入两个参数node和data, 分别表示当前节点的Node对象和当前节点的数据。</h4>
<div class="custom-tree-container">
<div class="block">
<p>使用render-content</p>
<el-tree :data="data1" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" :render-content="renderContent"></el-tree>
</div>
<div class="block">
<p>使用scoped slot</p>
<el-tree :data="data2" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button type="text" size="mini" @click="() => append(data)">Append</el-button>
<el-button type="text" size="mini" @click="() => remove(node, data)">Delete</el-button>
</span>
</span>
</el-tree>
</div>
</div>
</div>
</template>
<script>
let id = 1000
export default {
data () {
const data = [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}]
return {
data1: JSON.parse(JSON.stringify(data)),
data2: JSON.parse(JSON.stringify(data))
}
},
methods: {
append (data) {
const newChild = { id: id++, label: 'testtest', children: [] }
if (!data.children) {
this.$set(data, 'children', [])
}
data.children.push(newChild)
},
remove (node, data) {
const parent = node.parent
const children = parent.data.children || parent.data
const index = children.findIndex(d => d.id === data.id)
children.splice(index, 1)
},
renderContent (h, { node, data, store }) {
return (
<span class="custom-tree-node">
<span>{node.label}</span>
<span>
<el-button size="mini" type="text" on-click={ () => this.append(data) }>Append</el-button>
<el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
</span>
</span>)
}
}
}
</script>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
2.9. 在components下创建FilterTree.vue
<template>
<div>
<h1>节点过滤-通过关键字过滤树节点</h1>
<h4>在需要对节点进行过滤时, 调用 Tree 实例的filter方法, 参数为关键字。需要注意的是, 此时需要设置filter-node-method, 值为过滤函数。</h4>
<el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
<el-tree :data="data" :props="defaultProps" default-expand-all :filter-node-method="filterNode" ref="tree"></el-tree>
</div>
</template>
<script>
export default {
watch: {
filterText (val) {
this.$refs.tree.filter(val)
}
},
methods: {
filterNode (value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
},
data () {
return {
filterText: '',
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
2.10. 在components下创建AccordionTree.vue
<template>
<div>
<h1>手风琴模式</h1>
<h4>accordion是否每次只打开一个同级树节点展开。</h4>
<el-tree :data="data" :props="defaultProps" accordion></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>
2.11. 在components下创建DraggableTree.vue
<template>
<div>
<h1>可拖拽节点</h1>
<h4>通过draggable属性可让节点变为可拖拽。</h4>
<el-tree :data="data" node-key="id" default-expand-all @node-drag-start="handleDragStart" @node-drag-enter="handleDragEnter" @node-drag-leave="handleDragLeave"
@node-drag-over="handleDragOver" @node-drag-end="handleDragEnd" @node-drop="handleDrop" draggable :allow-drop="allowDrop" :allow-drag="allowDrag"></el-tree>
</div>
</template>
<script>
export default {
data () {
return {
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2',
children: [{
id: 11,
label: '三级 3-2-1'
}, {
id: 12,
label: '三级 3-2-2'
}, {
id: 13,
label: '三级 3-2-3'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleDragStart (node, ev) {
console.log('drag start', node)
},
handleDragEnter (draggingNode, dropNode, ev) {
console.log('tree drag enter: ', dropNode.label)
},
handleDragLeave (draggingNode, dropNode, ev) {
console.log('tree drag leave: ', dropNode.label)
},
handleDragOver (draggingNode, dropNode, ev) {
console.log('tree drag over: ', dropNode.label)
},
handleDragEnd (draggingNode, dropNode, dropType, ev) {
console.log('tree drag end: ', dropNode && dropNode.label, dropType)
},
handleDrop (draggingNode, dropNode, dropType, ev) {
console.log('tree drop: ', dropNode.label, dropType)
},
allowDrop (draggingNode, dropNode, type) {
if (dropNode.data.label === '二级 3-1') {
return type !== 'inner'
} else {
return true
}
},
allowDrag (draggingNode) {
return draggingNode.data.label.indexOf('三级 3-2-2') === -1
}
}
}
</script>
2.12. 运行项目, 访问http://localhost:8080/#/BaseTree
2.13. 运行项目, 访问http://localhost:8080/#/ShowCheckboxTree
2.14. 运行项目, 访问http://localhost:8080/#/DefaultExpandedCheckedKeysTree
2.15. 运行项目, 访问http://localhost:8080/#/DisabledTree
2.16. 运行项目, 访问http://localhost:8080/#/NodeKeyTree
2.17. 运行项目, 访问http://localhost:8080/#/RenderContentScopedSlotTree
2.18. 运行项目, 访问http://localhost:8080/#/FilterTree
2.19. 运行项目, 访问http://localhost:8080/#/AccordionTree
2.20. 运行项目, 访问http://localhost:8080/#/DraggableTree