feat(Cascader): watch value and reset options

This commit is contained in:
chenjiahan 2020-12-20 15:33:21 +08:00 committed by neverland
parent 42d319d478
commit a05da0644b
3 changed files with 87 additions and 28 deletions

View File

@ -38,9 +38,9 @@ export default {
### Props ### Props
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| ------------ | ------------------ | ---------------------- | --------- | | ------------ | ------------------ | ------------------ | --------- |
| title | 顶部标题 | _string_ | - | | title | 顶部标题 | _string_ | - |
| value | 选中项的值 | _string[] \| number[]_ | - | | value | 选中项的值 | _string \| number_ | - |
| options | 可选项数据源 | _Option[]_ | `[]` | | options | 可选项数据源 | _Option[]_ | `[]` |
| placeholder | 未选中时的提示文案 | _string_ | `请选择` | | placeholder | 未选中时的提示文案 | _string_ | `请选择` |
| active-color | 选中状态的高亮颜色 | _string_ | `#ee0a24` | | active-color | 选中状态的高亮颜色 | _string_ | `#ee0a24` |

View File

@ -5,12 +5,13 @@
is-link is-link
readonly readonly
:label="t('area')" :label="t('area')"
:value="base.value" :value="base.result"
:placeholder="t('selectArea')" :placeholder="t('selectArea')"
@click="base.show = true" @click="base.show = true"
/> />
<van-popup v-model="base.show" round position="bottom"> <van-popup v-model="base.show" round position="bottom">
<van-cascader <van-cascader
v-model="base.value"
:title="t('selectArea')" :title="t('selectArea')"
:options="t('options')" :options="t('options')"
@close="base.show = false" @close="base.show = false"
@ -24,12 +25,13 @@
is-link is-link
readonly readonly
:label="t('area')" :label="t('area')"
:value="customColor.value" :value="customColor.result"
:placeholder="t('selectArea')" :placeholder="t('selectArea')"
@click="customColor.show = true" @click="customColor.show = true"
/> />
<van-popup v-model="customColor.show" round position="bottom"> <van-popup v-model="customColor.show" round position="bottom">
<van-cascader <van-cascader
v-model="customColor.value"
:title="t('selectArea')" :title="t('selectArea')"
:options="t('options')" :options="t('options')"
active-color="#1989fa" active-color="#1989fa"
@ -64,20 +66,23 @@ export default {
base: { base: {
show: false, show: false,
value: '', value: '',
result: '',
}, },
customColor: { customColor: {
show: false, show: false,
value: '', value: null,
result: '',
}, },
}; };
}, },
methods: { methods: {
onFinish(type, { selectedOptions }) { onFinish(type, { value, selectedOptions }) {
const fieldValue = selectedOptions.map((option) => option.text).join('/'); const result = selectedOptions.map((option) => option.text).join('/');
this[type] = { this[type] = {
show: false, show: false,
value: fieldValue, value,
result,
}; };
}, },
}, },

View File

@ -7,8 +7,8 @@ const [createComponent, bem] = createNamespace('cascader');
export default createComponent({ export default createComponent({
props: { props: {
value: Array,
title: String, title: String,
value: [Number, String],
options: Array, options: Array,
placeholder: String, placeholder: String,
activeColor: String, activeColor: String,
@ -30,27 +30,80 @@ export default createComponent({
// reset options and tab // reset options and tab
}, },
value() { value(value) {
// reset options and tab if (value) {
const values = this.tabs.map((tab) => tab.selectedOption?.value);
if (values.indexOf(value) !== -1) {
return;
}
}
this.updateTabs();
}, },
}, },
created() { created() {
this.init(); this.updateTabs();
}, },
methods: { methods: {
init() { getSelectedOptionsByValue(options, value) {
for (let i = 0; i < options.length; i++) {
const option = options[i];
if (option.value === value) {
return [option];
}
if (option.children) {
const selectedOptions = this.getSelectedOptionsByValue(
option.children,
value
);
if (selectedOptions) {
return [option, ...selectedOptions];
}
}
}
},
updateTabs() {
if (this.value) { if (this.value) {
// const selectedOptions = this.getSelectedOptionsByValue(
} else { this.options,
this.value
);
if (selectedOptions) {
let optionsCursor = this.options;
this.tabs = selectedOptions.map((option) => {
const tab = {
options: optionsCursor,
selectedOption: option,
};
const next = optionsCursor.filter(
(item) => item.value === option.value
);
if (next.length) {
optionsCursor = next[0].children;
}
return tab;
});
this.activeTab = selectedOptions.length - 1;
return;
}
}
this.tabs = [ this.tabs = [
{ {
options: this.options, options: this.options,
selectedOption: null, selectedOption: null,
}, },
]; ];
}
}, },
onSelect(option, tabIndex) { onSelect(option, tabIndex) {
@ -82,6 +135,7 @@ export default createComponent({
tabIndex, tabIndex,
selectedOptions: this.tabs.map((tab) => tab.selectedOption), selectedOptions: this.tabs.map((tab) => tab.selectedOption),
}; };
this.$emit('input', option.value);
this.$emit('change', eventParams); this.$emit('change', eventParams);
if (!option.children) { if (!option.children) {