diff --git a/examples/docs/en-US/tree.md b/examples/docs/en-US/tree.md index 9d2ff46ed..760f813b6 100644 --- a/examples/docs/en-US/tree.md +++ b/examples/docs/en-US/tree.md @@ -1038,6 +1038,8 @@ Only one node among the same level can be expanded at one time. | 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 `false`. If the parameter is `true`, it only returns the currently selected array of sub-nodes. | | setCheckedKeys | set certain nodes to be checked, only works when `node-key` is assigned | (keys, leafOnly) Accept two parameters: 1. an array of node's keys to be checked 2. a boolean type parameter whose default value is `false`. If the parameter is `true`, it only returns the currently selected array of sub-nodes. | | setChecked | set node to be checked or not, only works when `node-key` is assigned | (key/data, checked, deep) Accept three parameters: 1. node's key or data to be checked 2. a boolean typed parameter indicating checked or not. 3. a boolean typed parameter indicating deep or not. | +| getHalfCheckedNodes | If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of nodes | - | +| getHalfCheckedKeys | If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of node's keys | - | | getCurrentKey | return the highlight node's key (null if no node is highlighted) | — | | getCurrentNode | return the highlight node (null if no node is highlighted) | — | | setCurrentKey | set highlighted node by key, only works when `node-key` is assigned | (key) the node's key to be highlighted | @@ -1054,6 +1056,7 @@ Only one node among the same level can be expanded at one time. | node-click | triggers when a node is clicked | three parameters: node object corresponding to the node clicked, `node` property of TreeNode, TreeNode itself | | node-contextmenu | triggers when a node is clicked by right button | four parameters: event, node object corresponding to the node clicked, `node` property of TreeNode, TreeNode itself | | check-change | triggers when the selected state of the node changes | three parameters: node object corresponding to the node whose selected state is changed, whether the node is selected, whether node's subtree has selected nodes | +| check | triggers after click checkbox of node | two parameters: node object corresponding to the node whose selected state is changed, tree checked status object which has four props: checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys | | current-change | triggers when current node changes | two parameters: node object corresponding to the current node, `node` property of TreeNode | | node-expand | triggers when current node open | three parameters: node object corresponding to the node opened, `node` property of TreeNode, TreeNode itself | | node-collapse | triggers when current node close | three parameters: node object corresponding to the node closed, `node` property of TreeNode, TreeNode itself | diff --git a/examples/docs/es/tree.md b/examples/docs/es/tree.md index 1168ba074..34c2c4d81 100644 --- a/examples/docs/es/tree.md +++ b/examples/docs/es/tree.md @@ -1036,6 +1036,8 @@ Solo puede ser expandido un nodo del mismo nivel a la vez. | getCheckedKeys | Si los nodos pueden ser seleccionados (`show-checkbox` es `true`), devuelve un array con las claves de los nodos seleccionados | (leafOnly) Acepta un booleano que por defecto es `false`. | | setCheckedKeys | Establece algunos nodos como seleccionados, solo si `node-key` está asignado | (keys, leafOnly) Acepta dos parametros: 1. un array de claves 2. un booleano cuyo valor por defecto es `false`. Si el parámetro es `true`, solo devuelve los nodos seleccionados | | setChecked | Establece si un nodo está seleccionado, solo funciona si `node-key` esta asignado | (key/data, checked, deep) Acepta tres parámetros: 1. la clave o dato del nodo a ser seleccionado 2. un booleano que indica si un nodo el nodo estará seleccionado 3. un booleanoque indica si se hará en profundidad | +| getHalfCheckedNodes | If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of nodes | - | +| getHalfCheckedKeys | If the node can be selected (`show-checkbox` is `true`), it returns the currently half selected array of node's keys | - | | getCurrentKey | devuelve la clave del nodo resaltado actualmente (null si no hay ninguno) | — | | getCurrentNode | devuelve el nodo resaltado (null si no hay ninguno) | — | | setCurrentKey | establece el nodo resaltado por la clave, solo funciona si `node-key` está asignado | (key) la clave del nodo a ser resaltado | @@ -1052,6 +1054,7 @@ Solo puede ser expandido un nodo del mismo nivel a la vez. | node-click | se lanza cuando un nodo es pinchado | tres parámetros: el objeto del nodo seleccionado, propiedad `node` de TreeNode y el TreeNode en si | | node-contextmenu | triggers when a node is clicked by right button | four parameters: event, node object corresponding to the node clicked, `node` property of TreeNode, TreeNode itself | | check-change | se lanza cuando el estado de selección del nodo cambia | tres parámetros: objeto nodo que se corresponde con el que ha cambiado, booleano que dice si esta seleccionado, booleano que dice si el nodo tiene hijos seleccionados | +| check | triggers after click checkbox of node | two parameters: node object corresponding to the node whose selected state is changed, tree checked status object which has four props: checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys | | current-change | cambia cuando el nodo actual cambia | dos parámetros: objeto nodo que se corresponde al nodo actual y propiedad `node` del TreeNode | | node-expand | se lanza cuando el nodo actual se abre | tres parámetros: el objeto del nodo abierto, propiedad `node` de TreeNode y el TreeNode en si | | node-collapse | se lanza cuando el nodo actual se cierra | tres parámetros: el objeto del nodo cerrado, propiedad `node` de TreeNode y el TreeNode en si | diff --git a/examples/docs/zh-CN/tree.md b/examples/docs/zh-CN/tree.md index 077bcaa89..9309c6442 100644 --- a/examples/docs/zh-CN/tree.md +++ b/examples/docs/zh-CN/tree.md @@ -1036,9 +1036,11 @@ | updateKeyChildren | 通过 keys 设置节点子元素,使用此方法必须设置 node-key 属性 | (key, data) 接收两个参数,1. 节点 key 2. 节点数据的数组 | | getCheckedNodes | 若节点可被选择(即 `show-checkbox` 为 `true`),则返回目前被选中的节点所组成的数组 | (leafOnly) 接收一个 boolean 类型的参数,若为 `true` 则仅返回被选中的叶子节点,默认值为 `false` | | setCheckedNodes | 设置目前勾选的节点,使用此方法必须设置 node-key 属性 | (nodes) 接收勾选节点数据的数组 | -| getCheckedKeys | 若节点可被选择(即 `show-checkbox` 为 `true`),则返回目前被选中的节点所组成的数组 | (leafOnly) 接收一个 boolean 类型的参数,若为 `true` 则仅返回被选中的叶子节点的 keys,默认值为 `false` | +| 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 | 获取当前被选中节点的 node,若没有节点被选中则返回 null | — | | setCurrentKey | 通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性 | (key) 待被选节点的 key | @@ -1055,6 +1057,7 @@ | 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、节点组件本身。 | diff --git a/packages/tree/src/model/tree-store.js b/packages/tree/src/model/tree-store.js index 5019850b1..99a453e70 100644 --- a/packages/tree/src/model/tree-store.js +++ b/packages/tree/src/model/tree-store.js @@ -158,7 +158,7 @@ export default class TreeStore { const childNodes = node.root ? node.root.childNodes : node.childNodes; childNodes.forEach((child) => { - if ((!leafOnly && child.checked) || (leafOnly && child.isLeaf && child.checked)) { + if (child.checked && (!leafOnly || (leafOnly && child.isLeaf))) { checkedNodes.push(child.data); } @@ -172,17 +172,30 @@ export default class TreeStore { } getCheckedKeys(leafOnly = false) { - const key = this.key; - const allNodes = this._getAllNodes(); - const keys = []; - allNodes.forEach((node) => { - if (!leafOnly || (leafOnly && node.isLeaf)) { - if (node.checked) { - keys.push((node.data || {})[key]); + return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]); + } + + getHalfCheckedNodes() { + const nodes = []; + const traverse = function(node) { + const childNodes = node.root ? node.root.childNodes : node.childNodes; + + childNodes.forEach((child) => { + if (child.indeterminate) { + nodes.push(child.data); } - } - }); - return keys; + + traverse(child); + }); + }; + + traverse(this); + + return nodes; + } + + getHalfCheckedKeys() { + return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]); } _getAllNodes() { diff --git a/packages/tree/src/tree-node.vue b/packages/tree/src/tree-node.vue index 74e4a2472..4a01a73a1 100644 --- a/packages/tree/src/tree-node.vue +++ b/packages/tree/src/tree-node.vue @@ -181,6 +181,15 @@ handleCheckChange(value, ev) { this.node.setChecked(ev.target.checked, !this.tree.checkStrictly); + this.$nextTick(() => { + const store = this.tree.store; + this.tree.$emit('check', this.node.data, { + checkedNodes: store.getCheckedNodes(), + checkedKeys: store.getCheckedKeys(), + halfCheckedNodes: store.getHalfCheckedNodes(), + halfCheckedKeys: store.getHalfCheckedKeys(), + }); + }); }, handleChildNodeExpand(nodeData, node, instance) { diff --git a/packages/tree/src/tree.vue b/packages/tree/src/tree.vue index 9def50723..4c4e2a25c 100644 --- a/packages/tree/src/tree.vue +++ b/packages/tree/src/tree.vue @@ -184,6 +184,12 @@ setChecked(data, checked, deep) { this.store.setChecked(data, checked, deep); }, + getHalfCheckedNodes() { + return this.store.getHalfCheckedNodes(); + }, + getHalfCheckedKeys() { + return this.store.getHalfCheckedKeys(); + }, setCurrentNode(node) { if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCurrentNode'); this.store.setUserCurrentNode(node); diff --git a/test/unit/specs/tree.spec.js b/test/unit/specs/tree.spec.js index 1b83a3803..d8defb53c 100644 --- a/test/unit/specs/tree.spec.js +++ b/test/unit/specs/tree.spec.js @@ -315,6 +315,26 @@ describe('Tree', () => { }, 10); }); + it('check', done => { + vm = getTreeVm(':props="defaultProps" show-checkbox @check="handleCheck"', { + methods: { + handleCheck(data, args) { + this.data = data; + this.args = args; + } + } + }); + const secondNode = document.querySelectorAll('.el-tree-node__content')[1]; + const nodeCheckbox = secondNode.querySelector('.el-checkbox'); + expect(nodeCheckbox).to.be.exist; + nodeCheckbox.click(); + setTimeout(() => { + expect(vm.args.checkedNodes.length).to.equal(3); + expect(vm.data.id).to.equal(2); + done(); + }, 10); + }); + it('setCheckedNodes', (done) => { vm = getTreeVm(':props="defaultProps" show-checkbox node-key="id"'); const tree = vm.$children[0];