mirror of
https://gitee.com/ElemeFE/element.git
synced 2024-11-29 18:57:36 +08:00
tree support accordion
This commit is contained in:
parent
39cbb051f1
commit
2072156e5b
@ -2,21 +2,36 @@
|
||||
const data = [{
|
||||
label: 'Level one 1',
|
||||
children: [{
|
||||
label: 'Level two 1-1'
|
||||
label: 'Level two 1-1',
|
||||
children: [{
|
||||
label: 'Level three 1-1-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 2',
|
||||
children: [{
|
||||
label: 'Level two 2-1'
|
||||
label: 'Level two 2-1',
|
||||
children: [{
|
||||
label: 'Level three 2-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 2-2'
|
||||
label: 'Level two 2-2',
|
||||
children: [{
|
||||
label: 'Level three 2-2-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 3',
|
||||
children: [{
|
||||
label: 'Level two 3-1'
|
||||
label: 'Level two 3-1',
|
||||
children: [{
|
||||
label: 'Level three 3-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 3-2'
|
||||
label: 'Level two 3-2',
|
||||
children: [{
|
||||
label: 'Level three 3-2-1'
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
|
||||
@ -107,21 +122,36 @@ Basic tree structure.
|
||||
data: [{
|
||||
label: 'Level one 1',
|
||||
children: [{
|
||||
label: 'Level two 1-1'
|
||||
label: 'Level two 1-1',
|
||||
children: [{
|
||||
label: 'Level three 1-1-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 2',
|
||||
children: [{
|
||||
label: 'Level two 2-1'
|
||||
label: 'Level two 2-1',
|
||||
children: [{
|
||||
label: 'Level three 2-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 2-2'
|
||||
label: 'Level two 2-2',
|
||||
children: [{
|
||||
label: 'Level three 2-2-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 3',
|
||||
children: [{
|
||||
label: 'Level two 3-1'
|
||||
label: 'Level two 3-1',
|
||||
children: [{
|
||||
label: 'Level three 3-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 3-2'
|
||||
label: 'Level two 3-2',
|
||||
children: [{
|
||||
label: 'Level three 3-2-1'
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
defaultProps: {
|
||||
@ -214,6 +244,69 @@ Used for node selection. In the following example, data for each layer is acquir
|
||||
```
|
||||
:::
|
||||
|
||||
### Accordion
|
||||
|
||||
Only one node among the same level can be expanded at one time.
|
||||
|
||||
::: demo
|
||||
```html
|
||||
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
data: [{
|
||||
label: 'Level one 1',
|
||||
children: [{
|
||||
label: 'Level two 1-1',
|
||||
children: [{
|
||||
label: 'Level three 1-1-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 2',
|
||||
children: [{
|
||||
label: 'Level two 2-1',
|
||||
children: [{
|
||||
label: 'Level three 2-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 2-2',
|
||||
children: [{
|
||||
label: 'Level three 2-2-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: 'Level one 3',
|
||||
children: [{
|
||||
label: 'Level two 3-1',
|
||||
children: [{
|
||||
label: 'Level three 3-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: 'Level two 3-2',
|
||||
children: [{
|
||||
label: 'Level three 3-2-1'
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleNodeClick(data) {
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### Attributes
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
@ -233,6 +326,7 @@ Used for node selection. In the following example, data for each layer is acquir
|
||||
| check-strictly | whether checked state of a node not affects its father and child nodes when `show-checkbox` is `true` | boolean | — | false |
|
||||
| default-checked-keys | array of keys of initially checked nodes | array | — | — |
|
||||
| filter-node-method | this function will be executed on each node when use filter method. if return `false`, tree node will be hidden. | Function(value, data, node) | — | — |
|
||||
| accordion | whether only one node among the same level can be expanded at one time | boolean | — | false |
|
||||
|
||||
### props
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|
@ -14,21 +14,36 @@
|
||||
const data = [{
|
||||
label: '一级 1',
|
||||
children: [{
|
||||
label: '二级 1-1'
|
||||
label: '二级 1-1',
|
||||
children: [{
|
||||
label: '三级 1-1-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: '一级 2',
|
||||
children: [{
|
||||
label: '二级 2-1'
|
||||
label: '二级 2-1',
|
||||
children: [{
|
||||
label: '三级 2-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: '二级 2-2'
|
||||
label: '二级 2-2',
|
||||
children: [{
|
||||
label: '三级 2-2-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: '一级 3',
|
||||
children: [{
|
||||
label: '二级 3-1'
|
||||
label: '二级 3-1',
|
||||
children: [{
|
||||
label: '三级 3-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: '二级 3-2'
|
||||
label: '二级 3-2',
|
||||
children: [{
|
||||
label: '三级 3-2-1'
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
|
||||
@ -119,21 +134,36 @@
|
||||
data: [{
|
||||
label: '一级 1',
|
||||
children: [{
|
||||
label: '二级 1-1'
|
||||
label: '二级 1-1',
|
||||
children: [{
|
||||
label: '三级 1-1-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: '一级 2',
|
||||
children: [{
|
||||
label: '二级 2-1'
|
||||
label: '二级 2-1',
|
||||
children: [{
|
||||
label: '三级 2-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: '二级 2-2'
|
||||
label: '二级 2-2',
|
||||
children: [{
|
||||
label: '三级 2-2-1'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
label: '一级 3',
|
||||
children: [{
|
||||
label: '二级 3-1'
|
||||
label: '二级 3-1',
|
||||
children: [{
|
||||
label: '三级 3-1-1'
|
||||
}]
|
||||
}, {
|
||||
label: '二级 3-2'
|
||||
label: '二级 3-2',
|
||||
children: [{
|
||||
label: '三级 3-2-1'
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
defaultProps: {
|
||||
@ -226,6 +256,69 @@
|
||||
```
|
||||
:::
|
||||
|
||||
### 手风琴模式
|
||||
|
||||
每次只打开一个同级树节点展开
|
||||
|
||||
::: demo
|
||||
```html
|
||||
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-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
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
@ -245,6 +338,7 @@
|
||||
| check-strictly | 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false | boolean | — | false |
|
||||
| default-checked-keys | 默认勾选的节点的 key 的数组 | array | — | — |
|
||||
| filter-node-method | 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏 | Function(value, data, node) | — | — |
|
||||
| accordion | 是否每次只打开一个同级树节点展开 | boolean | — | false |
|
||||
|
||||
### props
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|
@ -35,7 +35,8 @@
|
||||
:render-content="renderContent"
|
||||
v-for="child in node.childNodes"
|
||||
:key="getNodeKey(child)"
|
||||
:node="child">
|
||||
:node="child"
|
||||
@click.native="handleChildNodeClick(child)">
|
||||
</el-tree-node>
|
||||
</div>
|
||||
</collapse-transition>
|
||||
@ -45,10 +46,15 @@
|
||||
<script type="text/jsx">
|
||||
import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
|
||||
import ElCheckbox from 'element-ui/packages/checkbox';
|
||||
import emitter from 'element-ui/src/mixins/emitter';
|
||||
|
||||
export default {
|
||||
name: 'ElTreeNode',
|
||||
|
||||
componentName: 'ElTreeNode',
|
||||
|
||||
mixins: [emitter],
|
||||
|
||||
props: {
|
||||
node: {
|
||||
default() {
|
||||
@ -156,6 +162,10 @@
|
||||
if (!this.node.indeterminate) {
|
||||
this.node.setChecked(ev.target.checked, !this.tree.checkStrictly);
|
||||
}
|
||||
},
|
||||
|
||||
handleChildNodeClick(node) {
|
||||
this.broadcast('ElTreeNode', 'tree-node-click', node);
|
||||
}
|
||||
},
|
||||
|
||||
@ -186,6 +196,14 @@
|
||||
this.expanded = true;
|
||||
this.childNodeRendered = true;
|
||||
}
|
||||
|
||||
if(this.tree.accordion) {
|
||||
this.$on('tree-node-click', node => {
|
||||
if(this.node !== node) {
|
||||
this.node.collapse();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -5,7 +5,8 @@
|
||||
:node="child"
|
||||
:props="props"
|
||||
:key="getNodeKey(child)"
|
||||
:render-content="renderContent">
|
||||
:render-content="renderContent"
|
||||
@click.native="handleChildNodeClick(child)">
|
||||
</el-tree-node>
|
||||
<div class="el-tree__empty-block" v-if="!root.childNodes || root.childNodes.length === 0">
|
||||
<span class="el-tree__empty-text">{{ emptyText }}</span>
|
||||
@ -16,10 +17,25 @@
|
||||
<script type="text/ecmascript-6">
|
||||
import TreeStore from './model/tree-store';
|
||||
import {t} from 'element-ui/src/locale';
|
||||
import emitter from 'element-ui/src/mixins/emitter';
|
||||
|
||||
export default {
|
||||
name: 'ElTree',
|
||||
|
||||
mixins: [emitter],
|
||||
|
||||
components: {
|
||||
ElTreeNode: require('./tree-node.vue')
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
store: null,
|
||||
root: null,
|
||||
currentNode: null
|
||||
};
|
||||
},
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Array
|
||||
@ -64,40 +80,8 @@
|
||||
highlightCurrent: Boolean,
|
||||
currentNodeKey: [String, Number],
|
||||
load: Function,
|
||||
filterNodeMethod: Function
|
||||
},
|
||||
|
||||
created() {
|
||||
this.isTree = true;
|
||||
|
||||
this.store = new TreeStore({
|
||||
key: this.nodeKey,
|
||||
data: this.data,
|
||||
lazy: this.lazy,
|
||||
props: this.props,
|
||||
load: this.load,
|
||||
currentNodeKey: this.currentNodeKey,
|
||||
checkStrictly: this.checkStrictly,
|
||||
defaultCheckedKeys: this.defaultCheckedKeys,
|
||||
defaultExpandedKeys: this.defaultExpandedKeys,
|
||||
autoExpandParent: this.autoExpandParent,
|
||||
defaultExpandAll: this.defaultExpandAll,
|
||||
filterNodeMethod: this.filterNodeMethod
|
||||
});
|
||||
|
||||
this.root = this.store.root;
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
store: null,
|
||||
root: null,
|
||||
currentNode: null
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
ElTreeNode: require('./tree-node.vue')
|
||||
filterNodeMethod: Function,
|
||||
accordion: Boolean
|
||||
},
|
||||
|
||||
computed: {
|
||||
@ -156,7 +140,31 @@
|
||||
},
|
||||
setChecked(data, checked, deep) {
|
||||
this.store.setChecked(data, checked, deep);
|
||||
},
|
||||
handleChildNodeClick(node) {
|
||||
this.broadcast('ElTreeNode', 'tree-node-click', node);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.isTree = true;
|
||||
|
||||
this.store = new TreeStore({
|
||||
key: this.nodeKey,
|
||||
data: this.data,
|
||||
lazy: this.lazy,
|
||||
props: this.props,
|
||||
load: this.load,
|
||||
currentNodeKey: this.currentNodeKey,
|
||||
checkStrictly: this.checkStrictly,
|
||||
defaultCheckedKeys: this.defaultCheckedKeys,
|
||||
defaultExpandedKeys: this.defaultExpandedKeys,
|
||||
autoExpandParent: this.autoExpandParent,
|
||||
defaultExpandAll: this.defaultExpandAll,
|
||||
filterNodeMethod: this.filterNodeMethod
|
||||
});
|
||||
|
||||
this.root = this.store.root;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -354,4 +354,19 @@ describe('Tree', () => {
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it('accordion', done => {
|
||||
vm = getTreeVm(':props="defaultProps" accordion');
|
||||
const firstNode = vm.$el.querySelector('.el-tree-node__content');
|
||||
const secondNode = vm.$el.querySelector('.el-tree-node:nth-child(2) .el-tree-node__content');
|
||||
firstNode.click();
|
||||
setTimeout(() => {
|
||||
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true;
|
||||
secondNode.click();
|
||||
setTimeout(() => {
|
||||
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false;
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user