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 相关文章推荐
用js遍历 table的脚本
Jul 23 Javascript
JavaScript中的稀疏数组与密集数组[译]
Sep 17 Javascript
原生javascript兼容性测试实例
Jul 01 Javascript
从数组中随机取x条不重复数据的JS代码
Dec 24 Javascript
利用a标签自动解析URL分析网址实例
Oct 20 Javascript
DOM操作一些常用的属性汇总
Mar 13 Javascript
jQuery模拟黑客帝国矩阵效果实例
Jun 28 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
Sep 04 Javascript
Bootstrap模态框禁用空白处点击关闭
Oct 20 Javascript
js实现tab选项卡切换功能
Jan 13 Javascript
轻松实现jQuery添加删除按钮Click事件
Mar 13 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
May 28 jQuery
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递归函数返回值使用方法
2013/02/18 PHP
php获取网卡的MAC地址支持WIN/LINUX系统
2014/04/30 PHP
php实现微信公众平台账号自定义菜单类
2014/12/02 PHP
php ImageMagick windows下安装教程
2015/01/26 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
ThinkPHP模型详解
2015/07/27 PHP
ThinkPHP自定义Redis处理SESSION的实现方法
2016/05/16 PHP
JTrackBar水平拖动效果
2007/07/15 Javascript
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
js实现文章文字大小字号功能完整实例
2014/11/01 Javascript
ECMAScript 5严格模式(Strict Mode)介绍
2015/03/02 Javascript
JS实现控制表格行内容垂直对齐的方法
2015/03/30 Javascript
JS运动相关知识点小结(附弹性运动示例)
2016/01/08 Javascript
js+css实现回到顶部按钮(back to top)
2016/03/02 Javascript
JS简单设置下拉选择框默认值的方法
2016/08/20 Javascript
Javascript动画效果(1)
2016/10/11 Javascript
解析js如何获取css样式
2016/12/11 Javascript
前端js弹出框组件使用方法
2020/08/24 Javascript
TypeScript学习之强制类型的转换
2016/12/27 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
layui select动态添加option的实例
2018/03/07 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
2018/10/01 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
python让图片按照exif信息里的创建时间进行排序的方法
2015/03/16 Python
Python实现图片转字符画的示例
2017/08/22 Python
python3实现公众号每日定时发送日报和图片
2018/02/24 Python
Python和Go语言的区别总结
2019/02/20 Python
UGG美国官网:购买UGG雪地靴、拖鞋和鞋子
2017/12/31 全球购物
阿联酋航空丹麦官方网站:Emirates DK
2019/08/25 全球购物
群众路线教育实践活动心得体会(四风)
2014/11/03 职场文书
道德与公民自我评价
2015/03/09 职场文书
小学教师个人工作总结2015
2015/04/20 职场文书
心理健康教育培训研修感言
2015/11/18 职场文书
《山中访友》教学反思
2016/02/24 职场文书