ElementUI radio组件选中小改造


Posted in Javascript onAugust 12, 2019

ElementUI 是自己比较钟爱的一套 vue 组件库,自己好几个项目里都在用它。一直以来这些丰富的组件,让我能快速的搞定各种后台管理页面,极大地提高了工作效率。

但是不管什么软件,肯定都没办法称之为完美,而最近的几个小需求中,也发现了 element ui 的一些不足(也可能是因为自己的需求比较奇葩吧)。其中一点就是本文要提到的,radio 绑定对象类型值的问题。

具体现象就是,当通过 mapState 方法自动一个计算对象数组,然后将它绑定到 el-radio 上时,el-radio-group 里的 el-radio 无法根据其绑定值正确的显示 checked 状态。

例如下面这段代码:

<template>
 <div id="app">
  <el-radio-group
   v-model="checkedUser"
  >
   <el-radio
    v-for="(user, index) in users"
    :key="index"
    :label="user"
    :value="user"
   >
    {{ `${user.name}(${user.age}岁)` }}
   </el-radio >
  </el-radio-group>

  <h2>当前选中</h2>
  <pre>{{ checkedUser }}</pre>
 </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
 name: 'app',

 data () {
  return {
   checkedUser: {
    name: 'C',
    age: 1,
   },
  }
 },

 computed: {
  ...mapState({
   users: state => state.users
  })
 },
}
</script>

其中 users 为 vuex store 中的 state。

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
 state: {
  users: [
   {
    name: 'A',
    age: 18,
   },
   {
    name: 'B',
    age: 20,
   },
   {
    name: 'C',
    age: 1,
   },
  ]

 },
})

export default store

但当运行代码之后看到,第三个 el-radio 并没有像预期的那样处于选中状态。

ElementUI radio组件选中小改造

查看代码时发现,el-radio 里的 checked 是根据 this.model === this.label 来判断的(见代码),而当 this.model 和 this.label 都是对象是,它们必须是引用同一个对象才会“恒等”。

得益于 Vue 提供的 extends 属性,我们可以轻松的扩展官方原来的 el-radio 组件,对其稍加改造,就可以解决这个问题。

<template>
 <label
  class="el-radio"
  :class="[
   border && radioSize ? 'el-radio--' + radioSize : '',
   { 'is-disabled': isDisabled },
   { 'is-focus': focus },
   { 'is-bordered': border },
   { 'is-checked': isChecked }
  ]"
  role="radio"
  :aria-checked="isChecked"
  :aria-disabled="isDisabled"
  :tabindex="tabIndex"
  @keydown.space.stop.prevent="model = isDisabled ? model : label"
 >
  <span class="el-radio__input"
     :class="{
    'is-disabled': isDisabled,
    'is-checked': isChecked
   }"
  >
   <span class="el-radio__inner"></span>
   <input
    ref="radio"
    class="el-radio__original"
    :value="label"
    type="radio"
    aria-hidden="true"
    v-model="model"
    @focus="focus = true"
    @blur="focus = false"
    @change="handleChange"
    :name="name"
    :disabled="isDisabled"
    tabindex="-1"
   >
  </span>
  <span class="el-radio__label" @keydown.stop>
   <slot></slot>
   <template v-if="!$slots.default">{{label}}</template>
  </span>
 </label>
</template>

<script>
import { isEqual } from 'lodash'
import { Radio } from 'element-ui'

export default {
 name: 'MyRadio',

 // 使用 extemds 选项来扩展官方的 el-radio
 extends: Radio,

 computed: {
  // IMPORTANT: 改写部分,主要是支持 object 类型的值
  isChecked () {
   return isEqual(this.model, this.label)
  },
 },
}
</script>

改造完成后,引用这个组件并替换掉原来模板里用到的 el-radio,刷新页面后会发现,radio 的初始选中状态正常了。

ElementUI radio组件选中小改造

实际上,el-checkbox/el-checkbox-group 也有类似的问题,也是可以解决的,但看过源码之后,发现 el-checkbox 的一些逻辑与 el-radio 又有不小差别,毕竟它绑定的可能就是对象数组,所以具体处理起来会有些不一样,本文就不具体介绍了,如果各位有兴趣可以自行探索。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
效率高的Javscript字符串替换函数的benchmark
Aug 02 Javascript
Jquery下判断Id是否存在的代码
Jan 06 Javascript
jQuery 获取多选框的值及多选框中文的函数
May 16 Javascript
JavaScript动态添加事件之事件委托
Jul 12 Javascript
基于cssSlidy.js插件实现响应式手机图片轮播效果
Aug 30 Javascript
关于使用js算总价的问题
Jun 23 Javascript
使用JavaScript根据图片获取条形码的方法
Jul 04 Javascript
微信小程序日历/日期选择插件使用方法详解
Dec 28 Javascript
微信小程序图表插件wx-charts用法实例详解
May 20 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
Sep 09 Javascript
解决layer弹出层中表单不起作用的问题
Sep 09 Javascript
vue组件暴露和.js文件暴露接口操作
Aug 11 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
Aug 12 #Javascript
微信小程序实现页面分享onShareAppMessage
Aug 12 #Javascript
react实现antd线上主题动态切换功能
Aug 12 #Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
Aug 12 #Javascript
解析原来浏览器原生支持JS Base64编码解码
Aug 12 #Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
Aug 12 #Javascript
微信小程序实现页面跳转传递参数(实体,对象)
Aug 12 #Javascript
You might like
PHP面向对象继承用法详解(优化与减少代码重复)
2016/12/02 PHP
cakephp常见知识点汇总
2017/02/24 PHP
JavaScript入门学习书籍推荐
2008/06/12 Javascript
网页图片延时加载的js代码
2010/04/22 Javascript
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
jQuery实现类似滑动门切换效果的层切换
2013/09/23 Javascript
轻松创建nodejs服务器(6):作出响应
2014/12/18 NodeJs
使用jQuery获得内容以及内容的属性
2015/02/26 Javascript
JS+CSS实现的经典tab选项卡效果代码
2015/09/16 Javascript
基于jQuery实现仿微博发布框字数提示
2016/07/27 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
vue单页开发父子组件传值思路详解
2018/05/18 Javascript
layui实现数据分页功能(ajax异步)
2019/07/27 Javascript
js实现简单页面全屏
2019/09/17 Javascript
react ant Design手动设置表单的值操作
2020/10/31 Javascript
[15:23]教你分分钟做大人:虚空假面
2014/10/30 DOTA
[01:01:22]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
pygame学习笔记(6):完成一个简单的游戏
2015/04/15 Python
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
实现python版本的按任意键继续/退出
2016/09/26 Python
Python中装饰器兼容加括号和不加括号的写法详解
2017/07/05 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
2020/02/03 Python
Python pymsql模块的使用
2020/09/07 Python
delegate与普通函数的区别
2014/01/22 面试题
《棉鞋里的阳光》教学反思
2014/04/24 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
党员年终个人总结
2015/02/14 职场文书
乡镇科协工作总结2015
2015/05/19 职场文书
2016高考感言
2015/08/01 职场文书
环保建议书作文500字
2015/09/14 职场文书
三严三实·严以修身心得体会
2016/01/15 职场文书
导游词之新疆-喀纳斯
2019/10/10 职场文书
再次探讨go实现无限 buffer 的 channel方法
2021/06/13 Golang
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技
python套接字socket通信
2022/04/01 Python