Tree: add filter-node-method prop & filter method.

pull/1223/merge
Furybean 2016-11-22 00:08:22 +08:00 committed by 杨奕
parent 2c764d13fa
commit 59293a219e
7 changed files with 65 additions and 3 deletions

View File

@ -230,6 +230,7 @@ Used for node selection. In the following example, data for each layer is acquir
| show-checkbox | whether node is selectable | boolean | — | false |
| 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) | - | - |
### props
| Attribute | Description | Type | Accepted Values | Default |
@ -241,6 +242,7 @@ Used for node selection. In the following example, data for each layer is acquir
`Tree` has the following method, which returns the currently selected array of nodes.
| Method | Description | Parameters |
|---------- |-------- |---------- |
| filter | filter all tree nodes, filtered nodes will be hidden | Accept a parameter which will be used as first parameter for filter-node-method |
| getCheckedNodes | If the node can be selected (`show-checkbox` is `true`), it returns the currently selected array of nodes | Accept a boolean type parameter whose default value is `false`. <br>If the parameter is `true`, it only returns the currently selected array of sub-nodes.|
| setCheckedNodes | set certain nodes to be checked, only works when `node-key` is assigned | an array of nodes to be checked |
| getCheckedKeys | If the node can be selected (`show-checkbox` is `true`), it returns the currently selected array of node's keys | (leafOnly) Accept a boolean type parameter whose default value is `true`. <br>If the parameter is `true`, it only returns the currently selected array of sub-nodes.|

View File

@ -242,6 +242,7 @@
| show-checkbox | 节点是否可被选择 | boolean | — | false |
| check-strictly | 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false | boolean | — | false |
| default-checked-keys | 默认勾选的节点的 key 的数组 | array | — | — |
| filter-node-method | 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏 | Function(value, data, node) | - | - |
### props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
@ -253,6 +254,7 @@
`Tree` 拥有如下方法,返回目前被选中的节点数组:
| 方法名 | 说明 | 参数 |
|------|--------|------|
| filter | 对树节点进行筛选操作 | 接收一个任意类型的参数,该参数会在 filter-node-method 中作为第一个参数 |
| getCheckedNodes | 若节点可被选择(即 `show-checkbox``true`<br>则返回目前被选中的节点所组成的数组 | (leafOnly) 接收一个 boolean 类型的参数,若为 `true`<br>仅返回被选中的叶子节点,默认值为 `false` |
| setCheckedNodes | 设置目前勾选的节点,使用此方法必须设置 node-key 属性 | (nodes) 接收勾选节点数据的数组 |
| getCheckedKeys | 若节点可被选择(即 `show-checkbox``true`<br>则返回目前被选中的节点所组成的数组 | (leafOnly) 接收一个 boolean 类型的参数,若为 `true` 则仅返回被选中的叶子节点的 keys默认值为 `true` |

View File

@ -50,6 +50,7 @@ export default class Node {
this.data = null;
this.expanded = false;
this.parent = null;
this.visible = true;
for (let name in options) {
if (options.hasOwnProperty(name)) {

View File

@ -26,6 +26,37 @@ export default class Tree {
}
}
filter(value) {
const filterNodeMethod = this.filterNodeMethod;
const traverse = function(node) {
const childNodes = node.root ? node.root.childNodes : node.childNodes;
childNodes.forEach((child) => {
child.visible = filterNodeMethod.call(child, value, child.data, child);
traverse(child);
});
if (!node.visible && childNodes.length) {
let allHidden = true;
childNodes.forEach((child) => {
if (child.visible) allHidden = false;
});
if (node.root) {
node.root.visible = allHidden === false;
} else {
node.visible = allHidden === false;
}
}
if (node.visible && !node.isLeaf) node.expand();
};
traverse(this);
}
setData(newVal) {
const instanceChanged = newVal !== this.root.data;
this.root.setData(newVal);

View File

@ -1,7 +1,8 @@
<template>
<div class="el-tree-node"
@click.stop="handleClick"
:class="{ 'is-expanded': childNodeRendered && expanded, 'is-current': $tree.currentNode === _self }">
v-show="node.visible"
:class="{ 'is-expanded': childNodeRendered && expanded, 'is-current': $tree.currentNode === _self, 'is-hidden': !node.visible }">
<div class="el-tree-node__content"
:style="{ 'padding-left': (node.level - 1) * 16 + 'px' }"
@click="handleExpandIconClick">

View File

@ -57,7 +57,8 @@
default: false
},
highlightCurrent: Boolean,
load: Function
load: Function,
filterNodeMethod: Function
},
created() {
@ -73,7 +74,8 @@
defaultCheckedKeys: this.defaultCheckedKeys,
defaultExpandedKeys: this.defaultExpandedKeys,
autoExpandParent: this.autoExpandParent,
defaultExpandAll: this.defaultExpandAll
defaultExpandAll: this.defaultExpandAll,
filterNodeMethod: this.filterNodeMethod
});
},
@ -109,6 +111,10 @@
},
methods: {
filter(value) {
if (!this.filterNodeMethod) throw new Error('[Tree] filterNodeMethod is required when filter');
this.tree.filter(value);
},
getCheckedNodes(leafOnly) {
return this.tree.getCheckedNodes(leafOnly);
},

View File

@ -127,6 +127,25 @@ describe('Tree', () => {
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2);
});
it('filter-node-method', (done) => {
vm = getTreeVm(':props="defaultProps" :filter-node-method="filterNode"', {
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
}
}
});
const tree = vm.$refs.tree;
tree.filter('2-1');
setTimeout(() => {
expect(tree.$el.querySelectorAll('.el-tree-node.is-hidden').length).to.equal(7);
done();
}, 100);
});
it('autoExpandParent = true', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {