Kaynağa Gözat

Cascader: expose getCheckedNodes and fix options change bug (#16709)

Simona 6 yıl önce
ebeveyn
işleme
29838eaf81

+ 11 - 0
examples/docs/en-US/cascader.md

@@ -1936,6 +1936,11 @@ You can customize the content of cascader node.
 | visible-change | triggers when the dropdown appears/disappears | true when it appears, and false otherwise |
 | remove-tag | triggers when remove tag in multiple selection mode | the value of the tag which is removed |
 
+### Cascader Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+
 ### Cascader Slots
 | Slot Name | Description |
 |---------|-------------|
@@ -1955,6 +1960,12 @@ You can customize the content of cascader node.
 | change | triggers when the binding value changes | value |
 | expand-change | triggers when expand option changes | an array of the expanding node's parent nodes |
 
+### CascaderPanel Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+| clearCheckedNodes | clear checked nodes | - |
+
 ### CascaderPanel Slots
 | Slot Name | Description |
 |---------|-------------|

+ 11 - 0
examples/docs/es/cascader.md

@@ -1939,6 +1939,11 @@ Puede personalizar el contenido del nodo de cascada.
 | visible-change | se activa cuando aparece/desaparece el menú desplegable | verdadero cuando aparece, y falso de otra manera |
 | remove-tag | se activa cuando se quita la etiqueta en modo de selección múltiple | el valor de la etiqueta que se quita |
 
+### Cascader Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+
 ### Slots de Cascader
 | Nombre del slot | Descripción |
 |---------|-------------|
@@ -1958,6 +1963,12 @@ Puede personalizar el contenido del nodo de cascada.
 | change | se desencadena cuando cambia el valor ligado.         | valor |
 | expand-change | se desencadena cuando las opciones expandidas cambian | un array de los nodos padres del nodo en expansión |
 
+### CascaderPanel Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+| clearCheckedNodes | clear checked nodes | - |
+
 ### Slots de CascaderPanel
 | Nombre del slot | Descripción |
 |---------|-------------|

+ 11 - 0
examples/docs/fr-FR/cascader.md

@@ -1936,6 +1936,11 @@ Vous pouvez personnaliser le contenu du noeud cascader.
 | visible-change | Se déclenche lorsque le menu déroulant apparaît / disparaît | vrai quand il apparaît, et faux sinon |
 | remove-tag | Se déclenche lors de la suppression d'une balise en mode de sélection multiple | la valeur de la balise qui est supprimée |
 
+### Cascader Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+
 ### Cascader Slots
 | Slot Name | Description |
 |---------|-------------|
@@ -1955,6 +1960,12 @@ Vous pouvez personnaliser le contenu du noeud cascader.
 | change | Se déclenche lorsque la valeur de liaison change | value |
 | expand-change | Se déclenche lorsque l'option d'agrandissement change | an array of the expanding node's parent nodes |
 
+### CascaderPanel Methods
+| Method Name | Description | Parameters |
+| ---- | ---- | ---- |
+| getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` |
+| clearCheckedNodes | clear checked nodes | - |
+
 ### CascaderPanel Slots
 | Slot Name | Description |
 |---------|-------------|

+ 11 - 0
examples/docs/zh-CN/cascader.md

@@ -1915,6 +1915,11 @@
 | visible-change | 下拉框出现/隐藏时触发 | 出现则为 true,隐藏则为 false |
 | remove-tag | 在多选模式下,移除Tag时触发 | 移除的Tag对应的节点的值 |
 
+### Cascader Methods
+| 方法名 | 说明 | 参数 |
+| ---- | ---- | ---- |
+| getCheckedNodes | 获取选中的节点 | (leafOnly) 是否只是叶子节点,默认值为 `false` |
+
 ### Cascader Slots
 | 名称     | 说明 |
 |---------|-------------|
@@ -1934,6 +1939,12 @@
 | change | 当选中节点变化时触发 | 选中节点的值 |
 | expand-change | 当展开节点发生变化时触发 | 各父级选项值组成的数组 |
 
+### CascaderPanel Methods
+| 方法名 | 说明 | 参数 |
+| ---- | ---- | ---- |
+| getCheckedNodes | 获取选中的节点数组 | (leafOnly) 是否只是叶子节点,默认值为 `false` |
+| clearCheckedNodes | 清空选中的节点 | - |
+
 ### CascaderPanel Slots
 | 名称     | 说明 |
 |---------|-------------|

+ 22 - 17
packages/cascader-panel/src/cascader-panel.vue

@@ -195,22 +195,24 @@ export default {
       });
     },
     syncActivePath() {
-      let { checkedValue, store, multiple } = this;
-      if (isEmpty(checkedValue)) {
+      const { store, multiple, activePath, checkedValue } = this;
+
+      if (!isEmpty(activePath)) {
+        const nodes = activePath.map(node => this.getNodeByValue(node.getValue()));
+        this.expandNodes(nodes);
+      } else if (!isEmpty(checkedValue)) {
+        const value = multiple ? checkedValue[0] : checkedValue;
+        const checkedNode = this.getNodeByValue(value) || {};
+        const nodes = (checkedNode.pathNodes || []).slice(0, -1);
+        this.expandNodes(nodes);
+      } else {
         this.activePath = [];
         this.menus = [store.getNodes()];
-      } else {
-        checkedValue = multiple ? checkedValue[0] : checkedValue;
-        const checkedNode = this.getNodeByValue(checkedValue) || {};
-        const nodes = [];
-        let { parent } = checkedNode;
-        while (parent) {
-          nodes.unshift(parent);
-          parent = parent.parent;
-        }
-        nodes.forEach(node => this.handleExpand(node, true /* silent */));
       }
     },
+    expandNodes(nodes) {
+      nodes.forEach(node => this.handleExpand(node, true /* silent */));
+    },
     calculateCheckedNodePaths() {
       const { checkedValue, multiple } = this;
       const checkedValues = multiple
@@ -259,8 +261,9 @@ export default {
       }
     },
     handleExpand(node, silent) {
+      const { activePath } = this;
       const { level } = node;
-      const path = this.activePath.slice(0, level - 1);
+      const path = activePath.slice(0, level - 1);
       const menus = this.menus.slice(0, level);
 
       if (!node.isLeaf) {
@@ -268,15 +271,16 @@ export default {
         menus.push(node.children);
       }
 
-      if (valueEquals(path, this.activePath)) return;
-
       this.activePath = path;
       this.menus = menus;
 
       if (!silent) {
         const pathValues = path.map(node => node.getValue());
-        this.$emit('active-item-change', pathValues); // Deprecated
-        this.$emit('expand-change', pathValues);
+        const activePathValues = activePath.map(node => node.getValue());
+        if (!valueEquals(pathValues, activePathValues)) {
+          this.$emit('active-item-change', pathValues); // Deprecated
+          this.$emit('expand-change', pathValues);
+        }
       }
     },
     handleCheckChange(value) {
@@ -321,6 +325,7 @@ export default {
       };
       config.lazyLoad(node, resolve);
     },
+
     /**
      * public methods
     */

+ 15 - 7
packages/cascader/src/cascader.vue

@@ -307,12 +307,19 @@ export default {
       }
     },
     checkedValue(val) {
-      const { value } = this;
+      const { value, dropDownVisible } = this;
+      const { checkStrictly, multiple } = this.config;
+
       if (!isEqual(val, value) || isUndefined(value)) {
+        this.computePresentContent();
+        // hide dropdown when single mode
+        if (!multiple && !checkStrictly && dropDownVisible) {
+          this.toggleDropDownVisible(false);
+        }
+
         this.$emit('input', val);
         this.$emit('change', val);
         this.dispatch('ElFormItem', 'el.form.change', [val]);
-        this.computePresentContent();
       }
     },
     options: {
@@ -465,16 +472,13 @@ export default {
       });
     },
     computePresentContent() {
+      // nextTick is required, because checked nodes may not change right now
       this.$nextTick(() => {
-        const { multiple, checkStrictly } = this.config;
-        if (multiple) {
+        if (this.config.multiple) {
           this.computePresentTags();
           this.presentText = this.presentTags.length ? ' ' : null;
         } else {
           this.computePresentText();
-          if (!checkStrictly && this.dropDownVisible) {
-            this.toggleDropDownVisible(false);
-          }
         }
       });
     },
@@ -630,6 +634,10 @@ export default {
         this.updatePopper();
       }
     },
+
+    /**
+     * public methods
+    */
     getCheckedNodes(leafOnly) {
       return this.panel.getCheckedNodes(leafOnly);
     }