ElementUI Select 组件的 BUG
概要
本文用于记录 ElementUI
中 Select
组件的一个缺陷,并提供了一个解决该缺陷的方案(不魔改源码)。
- 该缺陷只有在特定的场景下才可以复现,不影响大多数场景的使用;
- 复现版本:所有版本。适配
Vue 3.x
的Element-Plus
没有该问题。
问题现象
先通过这张动图感受一下:
可以看到,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
的情况,显然 ElementUI
对 value
的处理比较完善。
那么我们修改下代码,在选项渲染后再设置 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
的项目中。
路漫漫其修远兮,吾将上下而求索。