现象
前端页面如下
tab1中对应的选择框是多选,tab2中选择框是单选,tab3中没有选择框。选择框用v-if控制显隐。 我们先在tab1和tab2中的选择框中都选上内容,然后切换到tab3,再切换回tab2,这时候是显示正常的,但是再切换回tab1,就会发现tab1选择框的数据丢失了。
分析
我们控制这个选择框的多选与否是通过计算属性实现的
:multiple="neMultiChoose"
而这个计算属性是怎么写的呢
neMultiChoose() {
if (this.aaa === 'xxx' && this.activeTab === 'yyy') return false;
...
return true;
},
this.activeTab就是当前激活的tab页。但是注意,问题其实就埋在这里,这样实现就会导致每个选择框的多选属性都是一样的。举个例子,比如我们现在在tab1页面,选择框此时确实是多选,但是tab2中的选择框也是多选的,只不过你看不到而已。这并不符合我们的预期。
再来看下为什么会出现上面的那个问题。在我们切换到tab3又切换到tab2的时候,这时候tab1和tab2中的选择框都是同时初始化的,那么此时tab2中的multiple属性是false,原来存储的数据是字符串,所以正常显示,但是此时tab1中的multiple属性也是false,但是通过v-model绑定的数据是数组,所以element会把这个数据置为字符串,所以原来的数据就会丢。
element这么处理的证据可以看他的源码
created() {
this.cachedPlaceHolder = this.currentPlaceholder = this.propPlaceholder;
if (this.multiple && !Array.isArray(this.value)) {
this.$emit('input', []);
}
if (!this.multiple && Array.isArray(this.value)) {
this.$emit('input', '');
}
this.debouncedOnInputChange = debounce(this.debounce, () => {
this.onInputChange();
});
this.debouncedQueryChange = debounce(this.debounce, (e) => {
this.handleQueryChange(e.target.value);
});
this.$on('handleOptionClick', this.handleOptionSelect);
this.$on('setSelected', this.setSelected);
},
解决
我们需要改计算属性,让他对每个选择框计算出来的值是各自计算的
neMultiChoose() {
return (key) => {
if (this.aaa === 'xxx') {
return !['dddd', 'eeee'].includes(key);
}
if (this.aaa === 'yyy') {
return !['ffff', 'gggg'].includes(key);
}
return true;
};
},
使用这个计算属性的时候:multiple="neMultiChoose(key)"
这样就可以