为什么el-tabs在切换时el-select的数据会丢失

454 阅读2分钟

现象

前端页面如下

无标题.png

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)" 这样就可以