el-radio的三个坑
最近在用 Vue3、element-plus 写一个基因数据库前端,在使用 element-plus 的 el-radio 时遇到了一些问题,特此记录。
需求:实现一个左侧菜单,点击菜单项时从后端获取相应数据,可以取消选择。详细需求不再赘述,和 PlantCADB中的类似。
问题一:点击 radio 时获取到的是 oldValue
第一次点击 radio 项时数据未变化,一开始并没有意识到是 oldValue 的问题,思路放在了“为什么无法获取 radio 第一次点击值”上。
之后,在控制台打印看了一下,才发现每次点击 radio 时获取到的是上一次点击的值,原来,一开始思路就偏了。
- 一开始的写法:绑定的是 click 点击事件,拿到的是旧值
<el-radio-group v-model="speciesRadio" size="large">
<el-radio-button :label="item.name" v-for="item in speciesList.list" :key="item.name"
@click="handleBtnClick">
<span class="card-item-span">{{item.name}}</span>
<el-tag type="info" round>{{item.value}}</el-tag>
</el-radio-button>
- 参考了一些资料,把@click改成了@change,就能拿到新值了,后面的@click请忽略,和其他业务逻辑有关
<el-radio-group v-model="speciesRadio" size="large">
<el-radio-button name="speciesRadio" :label="item.name" v-for="item in speciesFilterList"
:key="item.name" @change="handleBtnChange" @click="handleClick">
<span class="card-item-span">{{item.name}}</span>
<el-tag type="info" round>{{item.value}}</el-tag>
</el-radio-button>
</el-radio-group>
问题二:点击 radio 时触发两次点击事件
原因:同时触发了 input 标签和 label 标签的点击事件。
解决:拿到 tagName 的值,如果是 ‘INPUT’,直接return。
let handleRadioChange = (e) => {
if (e.target.tagName != 'INPUT') {
return
}
// 之后的业务逻辑
}
问题三:取消 radio 单选
根据项目需求,我觉得这个实现起来是最复杂的,但是基本思路也不难。拿到上一次的 radio 值,如果和本次值相同,就将 radio-group 里 v-model 绑定的值置为空。
根据问题一中对应的需求,成功拿到了 newValue ,那么,如何获取 oldValue ?
实现思路:设置一个变量存储 oldValue ,利用 Vue3 中的数据监视,数据变化时拿到当前值并赋给这个变量。当新旧值相同时,并不会触发 watch 中的业务逻辑,即变量值还是 oldValue 。此时,就可以判断新旧值是否相同,若相同,将v-model对应的值设为空。
业务逻辑比较复杂,此处附上简化版代码:
e.target.value == radioOldVal ? speciesRadio.value = '' : radioOldVal = e.target.value
以上,就是此次项目中遇到的关于 el-radio 的三个坑。