# Tree 树形控件
用清晰的层级结构展示信息,可展开或折叠。
# 基础用法
基础的树形结构展示。
一级 1
一级 2
一级 3
<j-tree :list="data" :props="defaultProps" @click="handleNodeClick"></j-tree>
<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>
显示代码 复制代码 复制代码
# 可选择
适用于需要选择层级时使用。
a
b
<j-tree
tKey="sku"
:list="data"
:props="props"
checkbox
@check="handleCheckChange">
</j-tree>
<script>
export default {
data() {
return {
data: [
{ size: 'a', sku: '1',
childList: [{ size: 'a1', sku: '1-1',
childList: [{ size: 'a11', sku: '1-1-1',
childList: [{ size: 'a111', sku: '1-1-1-1' }, { size: 'a112', sku: '1-1-1-2' }]
}, { size: 'a12', sku: '1-1-2' }] }]
},
{ size: 'b', sku: '2',
childList: [{ size: 'b1', sku: '2-1',
childList: [{ size: 'b11', sku: '2-1-1' }] }]
}
],
props: {
label: 'size',
children: 'childList'
},
count: 1
};
},
methods: {
handleCheckChange( checked, data,nodeData) {
console.log( checked, data,nodeData);
}
}
};
</script>
显示代码 复制代码 复制代码
# 默认展开和默认选中
可将 Tree 的某些节点设置为默认展开或默认选中
一级 1
一级 2
二级 2-1
二级 2-2
一级 3
1.分别通过default-opened和default-checked设置默认展开和默认选中的节点。需要注意的是,此时必须设置t-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的;2.也可设置数据中对应的$checked和$opened来达到默认选中,默认展开的效果;
<j-tree
:list="data"
checkbox
t-key="id"
:default-opened="[3]"
:default-checked="[5]"
:props="defaultProps">
</j-tree>
<script>
export default {
data() {
return {
data: [{
id: 1,
label: '一级 1',
$checked:true,
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
$opened:true,
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>
显示代码 复制代码 复制代码
# 展开/关闭所有选中节点和展开/关闭所有节点
可通过 tree 的指定方法达成所需效果
一级 1
一级 2
一级 3
<j-tree
:list="data"
ref="tree1"
checkbox
t-key="id"
:props="defaultProps">
</j-tree>
<j-button class="small" @click="$refs.tree1.openChecked()">展开选中节点</j-button>
<j-button class="small" @click="$refs.tree1.closeUnchecked()">折叠未选中添加节点</j-button>
<j-button class="small" @click="$refs.tree1.openAll()">展开所有节点</j-button>
<j-button class="small" @click="$refs.tree1.closeAll()">折叠所有节点</j-button>
<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',
children: [{
$checked:true,
id: 11,
label: '三级 1-1-1'
}, {
id: 12,
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>
显示代码 复制代码 复制代码
# 禁用状态
可将 Tree 的某些节点设置为禁用状态
一级 2
通过$disabled设置禁用状态。
<j-tree
:list="data"
checkbox
t-key="id"
:default-opened="[2, 3]"
:default-checked="[5]">
</j-tree>
<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>
显示代码 复制代码 复制代码
# 树节点的选择
本例展示如何获取和设置选中节点。获取和设置各有两种方式:通过 key。如果需要通过 key 来获取或设置,则必须设置t-key。
如果需要默认选中样式,可以使用setCurrentKey,前提是必须设置highlight-current属性
<j-tree
:list="data"
checkbox
opened-all
t-key="id"
ref="tree"
highlight-current
:props="defaultProps">
</j-tree>
<div class="buttons">
<j-button @click="getChecked">获取选中数据</j-button>
<j-button @click="setChecked">通过 key 设置</j-button>
<j-button @click="resetChecked">清空</j-button>
</div>
<script>
export default {
mounted(){
this.$refs.tree.setCurrentKey(1);
},
methods: {
getChecked() {
console.log(this.$refs.tree.getChecked());
},
setChecked() {
this.$refs.tree.setChecked([3]);
},
resetChecked() {
this.$refs.tree.setChecked([]);
}
},
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>
显示代码 复制代码 复制代码
# 自定义节点内容
节点的内容支持自定义,可以在节点区添加按钮或图标等内容
一级 1
二级 1-1
三级 1-1-1
三级 1-1-2
一级 2
二级 2-1
二级 2-2
一级 3
二级 3-1
二级 3-2
可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。使用render-content指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,所以render-content示例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。
<j-tree
ref="treeZdy"
:list="data"
t-key="id"
opened-all
@click="handleNodeClick">
<span class="custom-tree-node" slot-scope="{ vnode, data }">
<span>{{data.label}}</span>
<span style="margin-left:20px;">
<i class="j-icon icon-add-select" @click.stop="addChild(data)"></i>
<i class="j-icon icon-sami-select" @click.stop="deleteChild(data,vnode)"></i>
</span>
</span>
</j-tree>
<j-button @click="addActiveChild">添加子节点</j-button>
<script>
var id=1000;
export default {
data() {
const data = [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1',
children:[]
}, {
id: 10,
label: '三级 1-1-2',
children:[]
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1',
children:[]
}, {
id: 6,
label: '二级 2-2',
children:[]
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1',
children:[]
}, {
id: 8,
label: '二级 3-2',
children:[]
}]
}];
return {
data: JSON.parse(JSON.stringify(data)),
}
},
methods: {
handleNodeClick(data,vnode){
console.log(data,vnode);
},
addChild(data){
const newChild = {id:id++,label: 'testtest'+id, children: [] };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
},
deleteChild(data,vnode){
const parent = vnode.componentInstance.parent;
if(parent){
const index = parent.children.findIndex(d => d.id === data.id);
parent.children.splice(index, 1);
}else{
const index = this.data.findIndex(d => d.id === data.id);
this.data.splice(index, 1);
}
},
addActiveChild(){
// 当前子节点添加,若无选中节点则添加到根节点
this.$refs.treeZdy.appendActivedTree([{id:id++,label: 'testtest'+id, children: [] }])
// 当前子节点指定位置添加
//this.$refs.treeZdy.appendActivedTree([{id:id++,label: 'testtest'+id, children: [] }],1)
// 根节点添加
// this.$refs.treeZdy.appendActivedTree([{id:id++,label: 'testtest'+id, children: [] }],1,true)
}
}
};
</script>
<style>
.custom-tree-node{
width:50%;
display:flex;
}
.icon-add-select{
color:#257fea;
}
.icon-sami-select{
color:red;
}
</style>
显示代码 复制代码 复制代码
# 手风琴模式
对于同一级的节点,每次只能展开一个
一级 1
一级 2
一级 3
<j-tree
:list="data"
:props="defaultProps"
accordion
@click="handleNodeClick">
</j-tree>
<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>
显示代码 复制代码 复制代码
# Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| data | 展示数据 | array | — | — |
| empty-text | 内容为空的时候展示的文本 | String | — | — |
| t-key | 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的 | String | — | — |
| props | 配置选项,具体看下表 | object | — | — |
| render-after-opened | 是否在第一次展开某个树节点后才渲染其子节点 | boolean | — | true |
| opened-all | 是否默认展开所有节点 | boolean | — | false |
| default-opened | 默认展开的节点的 key 的数组 | array | — | — |
| checkbox | 节点是否可被选择 | boolean | — | false |
| default-checked | 默认勾选的节点的 key 的数组 | array | — | — |
| accordion | 是否每次只打开一个同级树节点展开 | boolean | — | false |
| check-level | 选择层级联动 | boolean | — | false |
# props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| label | 指定节点标签为节点对象的某个属性值 | string, function(data, node) | — | — |
| children | 指定子树为节点对象的某个属性值 | string | — | — |
| disabled | 指定节点选择框是否禁用为节点对象的某个属性值 | boolean, function(data, node) | — | — |
# 方法
Tree 内部使用了 Node 类型的对象来包装用户传入的数据,用来保存目前节点的状态。
Tree 拥有如下方法:
| 方法名 | 说明 | 参数 |
|---|---|---|
| getChecked | 若节点可被选择(即 checkbox 为 true),则返回目前被选中的节点所组成的数组,使用此方法必须设置 t-key 属性 | — |
| setChecked | 设置勾选的节点, 使用此方法必须设置 t-key 属性 | 勾选节点的 key 的数组 |
| openChecked | 展开所有复选框选中的节点 | — |
| closeUnchecked | 折叠所有复选框未选中的节点 | — |
| openAll | 展开所有节点 | — |
| closeAll | 折叠所有节点 | — |
| setCurrentKey | 默认选中节点样式 | — |
# Events
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| click | 节点被点击时的回调 | 共两个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node。 |
| check | 当复选框被点击的时候触发 | 共三个参数,依次为:树目前的选中状态对象、传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node |
| item-dblclick | 没有子集的节点被双击时的回调 | 共两个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node。 |
# Scoped Slot
| name | 说明 |
|---|---|
| — | 自定义树节点的内容,参数为 { vnode, data } |