ElementUI Select 组件的 BUG

ElementUI Select 组件的 BUG

概要

本文用于记录 ElementUISelect 组件的一个缺陷,并提供了一个解决该缺陷的方案(不魔改源码)。

  1. 该缺陷只有在特定的场景下才可以复现,不影响大多数场景的使用;
  2. 复现版本:所有版本。适配 Vue 3.xElement-Plus 没有该问题。

问题现象

先通过这张动图感受一下:

ElementUI Select 组件的 BUG_第1张图片

可以看到,Select的值3与选项中的333对应不上。上述概要中提到的特殊场景就是:选项是异步加载的,在这之前先打开了下拉框。

代码:

new Vue({
  el: '#app',
  data: { options: [] },
  computed: {
    selectValue() {
      const initialValue = 3
      const found = this.options.find((line) => line.value === initialValue);
      return found ? found.value : '';
    },
  },
  created() {
    setTimeout(() => {
      this.options = [
        {
          value: 1,
          label: '111',
        },
        {
          value: 2,
          label: '222',
        },
        {
          value: 3,
          label: '333',
        },
        {
          value: 4,
          label: '444',
        },
      ];
    }, 1500);
  }
})

实际期望

我们的期望是:在没有选项时,不显示 Select 的值,并且在选项加载成功后正确显示对应的选项。

相信通过代码,大家已经明白了问题所在,显然 ElementUI 内部是没有考虑到这种场景的,也就是说,在选项发生变化时(下拉列表打开),其内部没有根据选项处理 value 对应的 label

关于其细节,有兴趣的同学可以去翻翻相关源码。

解决方案

之前我们讨论了,选项发生变化时(下拉列表打开),ElementUI 内部没有做相应的处理,那我们换个思路:

假设选项已经正常渲染,此时我们去设置 value,是否会正常显示其对应的 label

答案是肯定的!这一点,我们也比较好猜,因为我们会经常遇到设置 value 的情况,显然 ElementUIvalue 的处理比较完善。

那么我们修改下代码,在选项渲染后再设置 value

const initialValue = 3

new Vue({
  el: '#app',
  data: { options: [], selectValue: "" },
  created() {
    setTimeout(() => {
      this.options = [
        {
          value: 1,
          label: '111',
        },
        {
          value: 2,
          label: '222',
        },
        {
          value: 3,
          label: '333',
        },
        {
          value: 4,
          label: '444',
        },
      ];
      // nextTick 是关键,确保了先渲染选项
      // 如果没有 nextTick,那结果和之前一样,逻辑上和计算属性没有区别
      this.$nextTick(() => {
        this.selectValue = initialValue
      })
    }, 1500);
  }
})

总结

个人经验,ElementUI 作为一个组件库,没有 Ant Design 完善,最近还需要一个表格组件相关的坑,不算 bug,但不够好用。Element-Plus 相对好用,但只适用于 Vue 3.x 的项目中。

路漫漫其修远兮,吾将上下而求索。

你可能感兴趣的:(ElementUI Select 组件的 BUG)