From 4b119e5813bf4b50031f45ce59d2fada7331b18f Mon Sep 17 00:00:00 2001 From: Simona <36978416+SimonaliaChen@users.noreply.github.com> Date: Thu, 25 Jul 2019 11:32:02 +0800 Subject: [PATCH] Cascader: expose getCheckedNodes and fix options change bug (#16709) --- examples/docs/en-US/cascader.md | 11 ++++++ examples/docs/es/cascader.md | 11 ++++++ examples/docs/fr-FR/cascader.md | 11 ++++++ examples/docs/zh-CN/cascader.md | 11 ++++++ .../cascader-panel/src/cascader-panel.vue | 39 +++++++++++-------- packages/cascader/src/cascader.vue | 22 +++++++---- 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/examples/docs/en-US/cascader.md b/examples/docs/en-US/cascader.md index 5374df8f158..5d13574f950 100644 --- a/examples/docs/en-US/cascader.md +++ b/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 | |---------|-------------| diff --git a/examples/docs/es/cascader.md b/examples/docs/es/cascader.md index eb30f4dda90..f842d766682 100644 --- a/examples/docs/es/cascader.md +++ b/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 | |---------|-------------| diff --git a/examples/docs/fr-FR/cascader.md b/examples/docs/fr-FR/cascader.md index 67ead4256bb..e46fc05d399 100644 --- a/examples/docs/fr-FR/cascader.md +++ b/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 | |---------|-------------| diff --git a/examples/docs/zh-CN/cascader.md b/examples/docs/zh-CN/cascader.md index d2b37bb2d63..017d43e4a41 100644 --- a/examples/docs/zh-CN/cascader.md +++ b/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 | 名称 | 说明 | |---------|-------------| diff --git a/packages/cascader-panel/src/cascader-panel.vue b/packages/cascader-panel/src/cascader-panel.vue index ba5c1dccd55..1d804166772 100644 --- a/packages/cascader-panel/src/cascader-panel.vue +++ b/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 */ diff --git a/packages/cascader/src/cascader.vue b/packages/cascader/src/cascader.vue index 15d56edeaa6..bb875229c42 100644 --- a/packages/cascader/src/cascader.vue +++ b/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); }