Эх сурвалжийг харах

Add check event and getHalfChecedNodes method for Tree (#9730)

FuryBean 7 жил өмнө
parent
commit
fe29af1b1f

+ 3 - 0
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 |

+ 3 - 0
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 |

+ 4 - 1
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、节点组件本身。 |

+ 24 - 11
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() {

+ 9 - 0
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) {

+ 6 - 0
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);

+ 20 - 0
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];