Tree: add defaultExpandKeys & defaultCheckedKeys. (#1088)

pull/1105/head
FuryBean 2016-11-16 15:35:46 +08:00 committed by cinwell.li
parent af4bca8abe
commit 5203280af1
12 changed files with 385 additions and 97 deletions

View File

@ -1,5 +1,5 @@
<script>
var data = [{
const data = [{
label: 'Level one 1',
children: [{
label: 'Level two 1-1'
@ -20,23 +20,17 @@
}]
}];
var regions = [{
const regions = [{
'name': 'region1'
}, {
'name': 'region2'
}];
var count = 1;
let count = 1;
var props = {
const props = {
label: 'name',
children: 'zones',
icon(data, node) {
if (node.isLeaf) {
return 'el-icon-close';
}
return 'el-icon-search';
}
children: 'zones'
};
var defaultProps = {
@ -53,10 +47,10 @@
console.log(data);
},
loadNode(node, resolve) {
if (node.level === -1) {
return resolve([{ name: 'region1' }, { name: 'region2' }]);
if (node.level === 0) {
return resolve([{ name: 'Root1' }, { name: 'Root2' }]);
}
if (node.level > 4) return resolve([]);
if (node.level > 3) return resolve([]);
var hasChild;
if (node.data.name === 'region1') {
hasChild = true;
@ -67,7 +61,7 @@
}
setTimeout(function() {
var data;
let data;
if (hasChild) {
data = [{
name: 'zone' + count++
@ -185,10 +179,10 @@ Used for node selection. In the following example, data for each layer is acquir
console.log(data);
},
loadNode(node, resolve) {
if (node.level === -1) {
return resolve([{ name: 'region1' }, { name: 'region2' }]);
if (node.level === 0) {
return resolve([{ name: 'Root1' }, { name: 'Root2' }]);
}
if (node.level > 4) return resolve([]);
if (node.level > 3) return resolve([]);
var hasChild;
if (node.data.name === 'region1') {

View File

@ -11,7 +11,7 @@
</style>
<script>
var data = [{
const data = [{
label: '一级 1',
children: [{
label: '二级 1-1'
@ -32,23 +32,17 @@
}]
}];
var regions = [{
const regions = [{
'name': 'region1'
}, {
'name': 'region2'
}];
var count = 1;
let count = 1;
var props = {
const props = {
label: 'name',
children: 'zones',
icon(data, node) {
if (node.isLeaf) {
return 'el-icon-close';
}
return 'el-icon-search';
}
children: 'zones'
};
var defaultProps = {
@ -65,10 +59,10 @@
console.log(data);
},
loadNode(node, resolve) {
if (node.level === -1) {
if (node.level === 0) {
return resolve([{ name: 'region1' }, { name: 'region2' }]);
}
if (node.level > 4) return resolve([]);
if (node.level > 3) return resolve([]);
var hasChild;
if (node.data.name === 'region1') {
hasChild = true;
@ -197,10 +191,10 @@
console.log(data);
},
loadNode(node, resolve) {
if (node.level === -1) {
if (node.level === 0) {
return resolve([{ name: 'region1' }, { name: 'region2' }]);
}
if (node.level > 4) return resolve([]);
if (node.level > 3) return resolve([]);
var hasChild;
if (node.data.name === 'region1') {
@ -236,11 +230,18 @@
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| data | 展示数据 | array | — | — |
| empty-text | 内容为空的时候展示的文本 | String | — | — |
| node-key | 每个树节点用来作为唯一标识的属性,整颗树应该是唯一的 | String | — | — |
| props | 配置选项,具体看下表 | object | — | — |
| load | 加载子树数据的方法 | function(node, resolve) | — | — |
| show-checkbox | 节点是否可被选择 | boolean | — | false |
| render-content | 树节点的内容区的渲染 Function | Function(h, { node } | - | - |
| highlight-current | 是否高亮当前选中节点,默认值是 false。| boolean | - | false |
| default-expand-all | 是否默认展开所有节点 | boolean | - | false |
| auto-expand-parent | 展开子节点的时候是否自动展开父节点 | boolean | — | true |
| default-expand-keys | 默认展开的节点的 key 的数组 | array | — | — |
| show-checkbox | 节点是否可被选择 | boolean | — | false |
| check-strictly | 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false | boolean | — | false |
| default-checked-keys | 默认勾选的节点的 key 的数组 | array | — | — |
### props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
@ -253,6 +254,7 @@
| 方法名 | 说明 | 参数 |
|------|--------|------|
| getCheckedNodes | 若节点可被选择(即 `show-checkbox``true`<br>则返回目前被选中的节点所组成的数组 | 接收一个 boolean 类型的参数,若为 `true`<br>仅返回被选中的叶子节点,默认值为 `false` |
| setCheckedNodes | 设置目前勾选的节点,使用此方法必须设置 node-keys 属性 | 接收勾选节点数据的数组 |
### Events
| 事件名称 | 说明 | 回调参数 |

View File

@ -6,6 +6,20 @@
cursor: default;
background: #ffffff;
border: 1px solid #d3dce6;
@e empty-block {
display: table;
min-height: 60px;
text-align: center;
width: 100%;
height: 100%;
}
@e empty-text {
display: table-cell;
vertical-align: middle;
color: #5e6d82;
}
}
@b tree-node {
@ -63,9 +77,10 @@
display: inline-block;
}
@e icon {
@e loading-icon {
display: inline-block;
vertical-align: middle;
margin-right: 4px;
font-size: 14px;
color: #99a9bf;
}
@ -77,7 +92,7 @@
display: none;
}
&.expanded > .el-tree-node__children {
&.is-expanded > .el-tree-node__children {
display: block;
}
}

View File

@ -1,4 +1,3 @@
let nodeIdSeed = 0;
import objectAssign from 'element-ui/src/utils/merge';
const reInitChecked = function(node) {
@ -27,7 +26,7 @@ const reInitChecked = function(node) {
};
const getPropertyFromData = function(node, prop) {
const props = node.props;
const props = node._tree.props;
const data = node.data || {};
const config = props[prop];
@ -40,6 +39,8 @@ const getPropertyFromData = function(node, prop) {
}
};
let nodeIdSeed = 0;
export default class Node {
constructor(options) {
this.id = nodeIdSeed++;
@ -48,9 +49,7 @@ export default class Node {
this.indeterminate = false;
this.data = null;
this.expanded = false;
this.props = null;
this.parent = null;
this.lazy = false;
for (let name in options) {
if (options.hasOwnProperty(name)) {
@ -59,7 +58,7 @@ export default class Node {
}
// internal
this.level = -1;
this.level = 0;
this.loaded = false;
this.childNodes = [];
this.loading = false;
@ -68,8 +67,39 @@ export default class Node {
this.level = this.parent.level + 1;
}
if (this.lazy !== true && this.data) {
const tree = this._tree;
if (!tree) {
throw new Error('[Node]_tree is required!');
}
tree.registerNode(this);
if (tree.lazy !== true && this.data) {
this.setData(this.data);
if (tree.defaultExpandAll) {
this.expanded = true;
}
} else if (this.level > 0 && tree.lazy && tree.defaultExpandAll) {
this.expand();
}
if (!this.data) return;
const defaultExpandedKeys = tree.defaultExpandedKeys;
const key = tree.key;
if (key && defaultExpandedKeys && defaultExpandedKeys.indexOf(this.key) !== -1) {
if (tree.autoExpandParent) {
let parent = this.parent;
while (parent.level > 0) {
parent.expanded = true;
parent = parent.parent;
}
}
this.expand();
}
if (tree.lazy) {
tree._initDefaultCheckedNode(this);
}
}
@ -87,7 +117,7 @@ export default class Node {
this.childNodes = [];
let children;
if (this.level === -1 && this.data instanceof Array) {
if (this.level === 0 && this.data instanceof Array) {
children = this.data;
} else {
children = getPropertyFromData(this, 'children') || [];
@ -106,15 +136,19 @@ export default class Node {
return getPropertyFromData(this, 'icon');
}
get key() {
const nodeKey = this._tree.key;
if (this.data) return this.data[nodeKey];
return null;
}
insertChild(child, index) {
if (!child) throw new Error('insertChild error: child is required.');
if (!(child instanceof Node)) {
objectAssign(child, {
parent: this,
lazy: this.lazy,
load: this.load,
props: this.props
_tree: this._tree
});
child = new Node(child);
}
@ -132,6 +166,7 @@ export default class Node {
const index = this.childNodes.indexOf(child);
if (index > -1) {
this._tree && this._tree.deregisterNode(child);
child.parent = null;
this.childNodes.splice(index, 1);
}
@ -154,14 +189,13 @@ export default class Node {
if (this.shouldLoadData()) {
this.loadData((data) => {
if (data instanceof Array) {
callback();
this.expanded = true;
if (callback) callback();
}
});
} else {
this.expanded = true;
if (callback) {
callback();
}
if (callback) callback();
}
}
@ -176,7 +210,7 @@ export default class Node {
}
shouldLoadData() {
return this.lazy === true && this.load && !this.loaded;
return this._tree.lazy === true && this._tree.load && !this.loaded;
}
get isLeaf() {
@ -185,7 +219,7 @@ export default class Node {
hasChild() {
const childNodes = this.childNodes;
if (!this.lazy || (this.lazy === true && this.loaded === true)) {
if (!this._tree.lazy || (this._tree.lazy === true && this.loaded === true)) {
return childNodes && childNodes.length > 0;
}
return true;
@ -195,7 +229,7 @@ export default class Node {
this.indeterminate = value === 'half';
this.checked = value === true;
const handleDeep = () => {
const handleDescendants = () => {
if (deep) {
const childNodes = this.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
@ -205,28 +239,30 @@ export default class Node {
}
};
if (this.shouldLoadData()) {
if (!this._tree.checkStrictly && this.shouldLoadData()) {
// Only work on lazy load data.
this.loadData(() => {
handleDeep();
handleDescendants();
}, {
checked: value !== false
});
} else {
handleDeep();
handleDescendants();
}
const parent = this.parent;
if (parent.level === -1) return;
if (!parent || parent.level === 0) return;
if (!this._tree.checkStrictly) {
reInitChecked(parent);
}
}
getChildren() { // this is data
const data = this.data;
if (!data) return null;
const props = this.props;
const props = this._tree.props;
let children = 'children';
if (props) {
children = props.children || 'children';
@ -259,7 +295,7 @@ export default class Node {
}
loadData(callback, defaultProps = {}) {
if (this.lazy === true && this.load && !this.loaded) {
if (this._tree.lazy === true && this._tree.load && !this.loaded && !this.loading) {
this.loading = true;
const resolve = (children) => {
@ -274,7 +310,7 @@ export default class Node {
}
};
this.load(this, resolve);
this._tree.load(this, resolve);
} else {
if (callback) {
callback.call(this);

View File

@ -8,37 +8,111 @@ export default class Tree {
}
}
this.nodesMap = {};
this.root = new Node({
data: this.data,
lazy: this.lazy,
props: this.props,
load: this.load
_tree: this
});
if (this.lazy && this.load) {
const loadFn = this.load;
loadFn(this.root, (data) => {
this.root.doCreateChildren(data);
this._initDefaultCheckedNodes();
});
} else {
this._initDefaultCheckedNodes();
}
}
setData(newVal) {
const instanceChanged = newVal !== this.root.data;
this.root.setData(newVal);
if (instanceChanged) {
this._initDefaultCheckedNodes();
}
}
_initDefaultCheckedNodes() {
const defaultCheckedKeys = this.defaultCheckedKeys || [];
const nodesMap = this.nodesMap;
defaultCheckedKeys.forEach((checkedKey) => {
const node = nodesMap[checkedKey];
if (node) {
node.setChecked(true, !this.checkStrictly);
}
});
}
_initDefaultCheckedNode(node) {
const defaultCheckedKeys = this.defaultCheckedKeys || [];
if (defaultCheckedKeys.indexOf(node.key) !== -1) {
node.setChecked(true, !this.checkStrictly);
}
}
setDefaultCheckedKey(newVal) {
if (newVal !== this.defaultCheckedKeys) {
this.defaultCheckedKeys = newVal;
this._initDefaultCheckedNodes();
}
}
registerNode(node) {
const key = this.key;
if (!key || !node || !node.data) return;
this.nodesMap[node.key] = node;
}
deregisterNode(node) {
const key = this.key;
if (!key || !node || !node.data) return;
delete this.nodesMap[node.key];
}
getCheckedNodes(leafOnly) {
const checkedNodes = [];
const walk = function(node) {
const traverse = function(node) {
const childNodes = node.root ? node.root.childNodes : node.childNodes;
childNodes.forEach(function(child) {
childNodes.forEach((child) => {
if ((!leafOnly && child.checked) || (leafOnly && child.isLeaf && child.checked)) {
checkedNodes.push(child.data);
}
walk(child);
traverse(child);
});
};
walk(this);
traverse(this);
return checkedNodes;
}
setCheckedNodes(array) {
const key = this.key;
const checkedKeys = {};
array.forEach((item) => {
checkedKeys[(item || {})[key]] = true;
});
const allNodes = [];
const nodesMap = this.nodesMap;
for (let nodeKey in nodesMap) {
if (nodesMap.hasOwnProperty(nodeKey)) {
allNodes.push(nodesMap[nodeKey]);
}
}
allNodes.sort((a, b) => a.level > b.level ? -1 : 1);
allNodes.forEach((node) => {
node.setChecked(!!checkedKeys[(node.data || {})[key]], !this.checkStrictly);
});
}
};

View File

@ -1,9 +1,9 @@
<template>
<div class="el-tree-node"
@click.stop="handleClick"
:class="{ expanded: childNodeRendered && expanded, 'is-current': $tree.currentNode === _self }">
:class="{ 'is-expanded': childNodeRendered && expanded, 'is-current': $tree.currentNode === _self }">
<div class="el-tree-node__content"
:style="{ 'padding-left': node.level * 16 + 'px' }"
:style="{ 'padding-left': (node.level - 1) * 16 + 'px' }"
@click="handleExpandIconClick">
<span
class="el-tree-node__expand-icon"
@ -18,7 +18,7 @@
</el-checkbox>
<span
v-if="node.loading"
class="el-tree-node__icon el-icon-loading">
class="el-tree-node__loading-icon el-icon-loading">
</span>
<node-content :node="node"></node-content>
</div>
@ -29,6 +29,7 @@
<el-tree-node
:render-content="renderContent"
v-for="child in node.childNodes"
:key="getNodeKey(child)"
:node="child">
</el-tree-node>
</div>
@ -89,10 +90,25 @@
'node.checked'(val) {
this.handleSelectChange(val, this.node.indeterminate);
},
'node.expanded'(val) {
this.expanded = val;
if (val) {
this.childNodeRendered = true;
}
}
},
methods: {
getNodeKey(node, index) {
const nodeKey = this.$tree.nodeKey;
if (nodeKey && node) {
return node.data[nodeKey];
}
return index;
},
handleSelectChange(checked, indeterminate) {
if (this.oldChecked !== checked && this.oldIndeterminate !== indeterminate) {
this.$tree.$emit('check-change', this.node.data, checked, indeterminate);
@ -112,31 +128,27 @@
target.nodeName.toUpperCase() === 'LABEL') return;
if (this.expanded) {
this.node.collapse();
this.expanded = false;
} else {
this.node.expand(() => {
this.expanded = true;
this.childNodeRendered = true;
});
this.node.expand();
}
this.$tree.$emit('node-click', this.node.data, this.node, this);
},
handleUserClick() {
if (this.node.indeterminate) {
this.node.setChecked(this.node.checked, true);
this.node.setChecked(this.node.checked, !this.$tree.checkStrictly);
}
},
handleCheckChange(ev) {
if (!this.node.indeterminate) {
this.node.setChecked(ev.target.checked, true);
this.node.setChecked(ev.target.checked, !this.$tree.checkStrictly);
}
}
},
created() {
var parent = this.$parent;
const parent = this.$parent;
if (parent.$isTree) {
this.$tree = parent;
@ -157,6 +169,11 @@
}
this.showCheckbox = tree.showCheckbox;
if (this.node.expanded) {
this.expanded = true;
this.childNodeRendered = true;
}
}
};
</script>

View File

@ -6,11 +6,15 @@
:props="props"
:render-content="renderContent">
</el-tree-node>
<div class="el-tree__empty-block" v-if="!tree.root.childNodes || tree.root.childNodes.length === 0">
<span class="el-tree__empty-text">{{ emptyText }}</span>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import Tree from './model/tree';
import { t } from 'element-ui/src/locale';
export default {
name: 'el-tree',
@ -19,6 +23,19 @@
data: {
type: Array
},
emptyText: {
type: String,
default: t('el.tree.emptyText')
},
nodeKey: String,
checkStrictly: Boolean,
defaultExpandAll: Boolean,
autoExpandParent: {
type: Boolean,
default: true
},
defaultCheckedKeys: Array,
defaultExpandedKeys: Array,
renderContent: Function,
showCheckbox: {
type: Boolean,
@ -38,19 +55,23 @@
default: false
},
highlightCurrent: Boolean,
load: {
type: Function
}
load: Function
},
created() {
this.$isTree = true;
this.tree = new Tree({
key: this.nodeKey,
data: this.data,
lazy: this.lazy,
props: this.props,
load: this.load
load: this.load,
checkStrictly: this.checkStrictly,
defaultCheckedKeys: this.defaultCheckedKeys,
defaultExpandedKeys: this.defaultExpandedKeys,
autoExpandParent: this.autoExpandParent,
defaultExpandAll: this.defaultExpandAll
});
},
@ -78,13 +99,20 @@
watch: {
data(newVal) {
this.tree.root.setData(newVal);
this.tree.setData(newVal);
},
defaultCheckedKeys(newVal) {
this.tree.setDefaultCheckedKey(newVal);
}
},
methods: {
getCheckedNodes(leafOnly) {
return this.tree.getCheckedNodes(leafOnly);
},
setCheckedNodes(nodes) {
if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCheckedNodes');
this.tree.setCheckedNodes(nodes);
}
}
};

View File

@ -77,6 +77,9 @@ export default {
confirmFilter: 'filtern',
resetFilter: 'rücksetzen',
clearFilter: 'alles'
},
tree: {
emptyText: 'keine Daten'
}
}
};

View File

@ -77,6 +77,9 @@ export default {
confirmFilter: 'Confirm',
resetFilter: 'Reset',
clearFilter: 'All'
},
tree: {
emptyText: 'No Data'
}
}
};

View File

@ -77,6 +77,9 @@ export default {
confirmFilter: 'Confirmar',
resetFilter: 'Limpar',
clearFilter: 'Todos'
},
tree: {
emptyText: 'Sem dados'
}
}
};

View File

@ -77,6 +77,9 @@ export default {
confirmFilter: '筛选',
resetFilter: '重置',
clearFilter: '全部'
},
tree: {
emptyText: '暂无数据'
}
}
};

View File

@ -1,5 +1,7 @@
import { createVue, destroyVM } from '../util';
const DELAY = 10;
describe('Tree', () => {
let vm;
afterEach(() => {
@ -9,30 +11,44 @@ describe('Tree', () => {
const getTreeVm = (props, options) => {
return createVue(Object.assign({
template: `
<el-tree :data="data" ${ props }></el-tree>
<el-tree ref="tree" :data="data" ${ props }></el-tree>
`,
data() {
return {
defaultExpandedKeys: [],
defaultCheckedKeys: [],
clickedNode: null,
count: 1,
data: [{
id: 1,
label: '一级 1',
children: [{
label: '二级 1-1'
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}],
@ -45,11 +61,13 @@ describe('Tree', () => {
}, options), true);
};
const ALL_NODE_COUNT = 9;
it('create', () => {
vm = getTreeVm(':props="defaultProps"');
expect(document.querySelector('.el-tree')).to.exist;
expect(document.querySelectorAll('.el-tree > .el-tree-node').length).to.equal(3);
expect(document.querySelectorAll('.el-tree .el-tree-node').length).to.equal(8);
expect(document.querySelectorAll('.el-tree .el-tree-node').length).to.equal(ALL_NODE_COUNT);
vm.data[1].children = [{ label: '二级 2-1' }];
const tree = vm.$children[0];
expect(tree.children).to.deep.equal(vm.data);
@ -63,16 +81,25 @@ describe('Tree', () => {
}
}
});
const firstNode = document.querySelector('.el-tree-node__content');
const firstNode = vm.$el.querySelector('.el-tree-node__content');
firstNode.click();
expect(vm.clickedNode.label).to.equal('一级 1');
vm.$nextTick(() => {
expect(document.querySelector('.el-tree-node').classList.contains('expanded')).to.true;
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.true;
firstNode.click();
vm.$nextTick(() => {
expect(document.querySelector('.el-tree-node').classList.contains('expanded')).to.false;
setTimeout(() => {
expect(vm.$el.querySelector('.el-tree-node').classList.contains('is-expanded')).to.false;
done();
}, DELAY);
}, DELAY);
});
it('emptyText', (done) => {
vm = getTreeVm(':props="defaultProps"');
vm.data = [];
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.el-tree__empty-block').length).to.equal(1);
done();
});
});
@ -86,12 +113,62 @@ describe('Tree', () => {
});
});
it('defaultExpandAll', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all');
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(ALL_NODE_COUNT);
});
it('defaultExpandedKeys', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {
this.defaultExpandedKeys = [1, 3];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(2);
});
it('autoExpandParent = true', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id"', {
created() {
this.defaultExpandedKeys = [111];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(3);
});
it('autoExpandParent = false', () => {
vm = getTreeVm(':props="defaultProps" :default-expanded-keys="defaultExpandedKeys" node-key="id" :auto-expand-parent="false"', {
created() {
this.defaultExpandedKeys = [111];
}
});
expect(vm.$el.querySelectorAll('.el-tree-node.is-expanded').length).to.equal(1);
});
it('defaultCheckedKeys & check-strictly = false', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id"', {
created() {
this.defaultCheckedKeys = [1];
}
});
expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(3);
});
it('defaultCheckedKeys & check-strictly', () => {
vm = getTreeVm(':props="defaultProps" default-expand-all show-checkbox :default-checked-keys="defaultCheckedKeys" node-key="id" check-strictly', {
created() {
this.defaultCheckedKeys = [1];
}
});
expect(vm.$el.querySelectorAll('.el-checkbox .is-checked').length).to.equal(1);
});
it('show checkbox', done => {
vm = getTreeVm(':props="defaultProps" show-checkbox');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[2];
const secondNode = document.querySelectorAll('.el-tree-node__content')[3];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
expect(nodeCheckbox).to.exist;
expect(nodeCheckbox).to.be.exist;
nodeCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedNodes(true).length).to.equal(2);
@ -104,6 +181,39 @@ describe('Tree', () => {
});
});
it('setCheckedNodes', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[3];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
expect(nodeCheckbox).to.be.exist;
nodeCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(3);
expect(tree.getCheckedNodes(true).length).to.equal(2);
vm.$nextTick(() => {
tree.setCheckedNodes([]);
expect(tree.getCheckedNodes().length).to.equal(0);
done();
});
});
it('check strictly', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox check-strictly');
const tree = vm.$children[0];
const secondNode = document.querySelectorAll('.el-tree-node__content')[3];
const nodeCheckbox = secondNode.querySelector('.el-checkbox');
nodeCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(1);
expect(tree.getCheckedNodes(true).length).to.equal(0);
const firstLeaf = secondNode.nextElementSibling.querySelector('.el-tree-node__content');
const leafCheckbox = firstLeaf.querySelector('.el-checkbox');
vm.$nextTick(() => {
leafCheckbox.click();
expect(tree.getCheckedNodes().length).to.equal(2);
done();
});
});
it('render content', () => {
vm = getTreeVm(':props="defaultProps" :render-content="renderContent"', {
methods: {
@ -127,10 +237,10 @@ describe('Tree', () => {
vm = getTreeVm(':props="defaultProps" lazy :load="loadNode" show-checkbox', {
methods: {
loadNode(node, resolve) {
if (node.level === -1) {
if (node.level === 0) {
return resolve([{ label: 'region1' }, { label: 'region2' }]);
}
if (node.level > 3) return resolve([]);
if (node.level > 4) return resolve([]);
setTimeout(() => {
resolve([{
label: 'zone' + this.count++