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 相关文章推荐
IE无法设置短域名下Cookie
Sep 23 Javascript
Node.js和PHP根据ip获取地理位置的方法
Mar 14 Javascript
JavaScript表格常用操作方法汇总
Apr 15 Javascript
javascript删除数组重复元素的方法汇总
Jun 24 Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 Javascript
AngularJS入门教程之ng-class 指令用法
Aug 01 Javascript
js中判断变量类型函数typeof的用法总结
Aug 09 Javascript
node.js爬虫爬取拉勾网职位信息
Mar 14 Javascript
微信小程序返回多级页面的实现方法
Oct 27 Javascript
解决低版本的浏览器不支持es6的import问题
Mar 09 Javascript
解决vue axios的封装 请求状态的错误提示问题
Sep 25 Javascript
基于vue的验证码组件的示例代码
Jan 22 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
双料怀旧--SHARP GF515的维护、修理和简单调试
2021/03/02 无线电
解决MySQL中文输出变成问号的问题
2008/06/05 PHP
PHP对象转换为数组函数(递归方法)
2012/02/04 PHP
使用php发送有附件的电子邮件-(PHPMailer使用的实例分析)
2013/04/26 PHP
PHP图片库imagemagick安装方法
2014/09/23 PHP
php堆排序实现原理与应用方法
2015/01/03 PHP
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
页面右下角弹出提示框示例代码js版
2013/08/02 Javascript
禁用JavaScript控制台调试的方法
2014/03/07 Javascript
node.js中的fs.mkdirSync方法使用说明
2014/12/17 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
JS实现上传图片实时预览功能
2017/05/22 Javascript
原生JS+Canvas实现五子棋游戏实例
2017/06/19 Javascript
JavaScript数据类型的存储方法详解
2017/08/25 Javascript
vue实现输入框的模糊查询的示例代码(节流函数的应用场景)
2019/09/01 Javascript
微信小程序 wx:for 与 wx:for-items 与 wx:key的正确用法
2020/05/19 Javascript
vue 弹出遮罩层样式实例
2020/07/22 Javascript
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
python调用staf自动化框架的方法
2018/12/26 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
详解pandas.DataFrame中删除包涵特定字符串所在的行
2019/04/04 Python
关于ResNeXt网络的pytorch实现
2020/01/14 Python
Tensorflow实现部分参数梯度更新操作
2020/01/23 Python
Python 格式化打印json数据方法(展开状态)
2020/02/27 Python
Python Flask异步发送邮件实现方法解析
2020/08/01 Python
IE10 Error.stack 让脚本调试更加方便快捷
2013/04/22 HTML / CSS
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
美国在线自行车商店:Jenson USA
2018/05/22 全球购物
Final类有什么特点
2012/04/25 面试题
幼儿园大班评语大全
2014/04/17 职场文书
领导党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
职代会闭幕词
2015/01/28 职场文书
Python实现归一化算法详情
2022/03/18 Python
golang操作redis的客户端包有多个比如redigo、go-redis
2022/04/14 Golang