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 相关文章推荐
JavaScript全局函数使用简单说明
Mar 11 Javascript
基于jQuery的模仿新浪微博时间的组件
Oct 04 Javascript
浅谈JavaScript编程语言的编码规范
Oct 21 Javascript
解析js如何获取当前url中的参数值并复制给input
Jun 23 Javascript
javascript实现通过表格绘制颜色填充矩形的方法
Apr 21 Javascript
AngularJS单选框及多选框实现双向动态绑定
Jan 13 Javascript
JavaScript实现计算圆周率到小数点后100位的方法示例
May 08 Javascript
在vue使用clipboard.js进行一键复制文本的实现示例
Jan 15 Javascript
laydate只显示时分 不显示秒的功能实现方法
Sep 28 Javascript
vue实现短信验证码输入框
Apr 17 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
Jul 26 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
Aug 17 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实现的DES加密解密实例代码
2016/04/06 PHP
功能强大的php文件上传类
2016/08/29 PHP
详解PHP归并排序的实现
2016/10/18 PHP
JavaScript函数、方法、对象代码
2008/10/29 Javascript
json 入门基础教程 推荐
2009/10/31 Javascript
JS实现点击图片在当前页面放大并可关闭的漂亮效果
2013/10/18 Javascript
JavaScript Math.ceil() 函数使用介绍
2013/12/11 Javascript
JavaScript也谈内存优化
2014/06/06 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
深入理解setTimeout函数和setInterval函数
2016/05/20 Javascript
Jquery和Js获得元素标签名称的方法总结
2016/10/08 Javascript
jQuery实现在HTML文档加载完毕后自动执行某个事件的方法
2017/05/08 jQuery
vuex的使用及持久化state的方式详解
2018/01/23 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
详解element-ui表格中勾选checkbox,高亮当前行
2019/09/02 Javascript
Python的lambda匿名函数的简单介绍
2013/04/25 Python
简单使用Python自动生成文章
2014/12/25 Python
Python发送form-data请求及拼接form-data内容的方法
2016/03/05 Python
python使用turtle库绘制树
2018/06/25 Python
Python实现快速傅里叶变换的方法(FFT)
2018/07/21 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
Python求均值,方差,标准差的实例
2019/06/29 Python
python Django编写接口并用Jmeter测试的方法
2019/07/31 Python
django迁移文件migrations的实现
2020/03/31 Python
使用已经得到的keras模型识别自己手写的数字方式
2020/06/29 Python
Pycharm如何自动生成头文件注释
2020/11/14 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
pycharm配置python 设置pip安装源为豆瓣源
2021/02/05 Python
Laura官网:加拿大女性的顶级时尚目的地
2019/09/20 全球购物
银行介绍信范文
2014/01/10 职场文书
小学见习报告
2015/06/23 职场文书
谢师宴家长答谢词
2015/09/30 职场文书
2016七夕情人节感言
2015/12/09 职场文书
导游词之张家界
2019/10/31 职场文书
用Python爬取英雄联盟的皮肤详细示例
2021/12/06 Python