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 写类方式之四
Jul 05 Javascript
JS使用for循环遍历Table的所有单元格内容
Aug 21 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
Sep 25 Javascript
简单的jQuery banner图片轮播实例代码
Mar 04 Javascript
jQuery实现的鼠标经过时变宽的效果(附demo源码)
Apr 28 Javascript
jQuery grep()方法详解及实例代码
Oct 30 Javascript
jQuery加密密码到cookie的实现代码
Apr 18 jQuery
Javascript中类式继承和原型式继承的实现方法和区别之处
Apr 25 Javascript
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
微信接入之获取用户头像的方法步骤
Sep 23 Javascript
如何使用Jquery动态生成二级选项列表
Feb 06 jQuery
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
Feb 09 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 unset全局变量运用问题的深入解析
2013/06/17 PHP
php使用mysqli向数据库添加数据的方法
2015/03/20 PHP
php 算法之实现相对路径的实例
2017/10/17 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
2019/04/17 PHP
php实现对文件压缩简单的方法
2019/09/29 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
js函数使用技巧之 setTimeout(function(){},0)
2009/02/09 Javascript
javascript学习笔记(五)正则表达式
2011/04/08 Javascript
jQuery Jcrop插件实现图片选取功能
2011/11/23 Javascript
Node.js测试中的Mock文件系统详解
2016/11/21 Javascript
angular.js+node.js实现下载图片处理详解
2017/03/31 Javascript
深入理解Javascript中的作用域链和闭包
2017/04/25 Javascript
Bootstrap输入框组件使用详解
2017/06/09 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
2017/08/28 Javascript
详解vue项目首页加载速度优化
2017/10/18 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
2017/12/13 Javascript
微信小程序画布圆形进度条显示效果
2020/11/17 Javascript
nuxt 页面路由配置,主页轮播组件开发操作
2020/11/05 Javascript
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
python模块之time模块(实例讲解)
2017/09/13 Python
python数据封装json格式数据
2018/03/04 Python
Python类的继承、多态及获取对象信息操作详解
2019/02/28 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
2020/06/05 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
Python3爬虫中Ajax的用法
2020/07/10 Python
Python根据字典的值查询出对应的键的方法
2020/09/30 Python
python 监控服务器是否有人远程登录(详细思路+代码)
2020/12/18 Python
英国女性时尚品牌:Apricot
2018/12/04 全球购物
电气技术员岗位职责
2013/11/19 职场文书
护理工作感言
2014/01/16 职场文书
庆七一活动总结
2014/08/27 职场文书
小学生家长意见
2015/06/03 职场文书
2015年科学教研组工作总结
2015/07/22 职场文书
小学学习委员竞选稿
2015/11/20 职场文书
Python天气语音播报小助手
2021/09/25 Python
python使用BeautifulSoup 解析HTML
2022/04/24 Python