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 相关文章推荐
input、button的不同type值在ajax提交表单时导致的陷阱
Feb 24 Javascript
JS禁用页面上所有控件的实现方法(附demo源码下载)
Dec 17 Javascript
jquery跟随屏幕滚动效果的实现代码
Apr 13 Javascript
js编写当天简单日历效果【实现代码】
May 03 Javascript
JS正则匹配中文的方法示例
Jan 06 Javascript
微信小程序 label 组件详解及简单实例
Jan 10 Javascript
node.js学习之断言assert的使用示例
Sep 28 Javascript
通过fastclick源码分析彻底解决tap“点透”
Dec 24 Javascript
通过一次报错详细谈谈Point事件
May 17 Javascript
Vue实现日历小插件
Jun 26 Javascript
百度小程序之间的页面通信过程详解
Jul 18 Javascript
layui.tree组件的使用以及搜索节点功能的实现
Sep 26 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
用Socket发送电子邮件(利用需要验证的SMTP服务器)
2006/10/09 PHP
mysql limit查询优化分析
2008/11/12 PHP
PHP实现UTF8二进制及明文字符串的转化功能示例
2017/11/20 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
初学JavaScript_03(ExtJs Grid的简单使用)
2008/10/02 Javascript
js获取当前日期代码适用于网页头部
2013/06/27 Javascript
jquery中的on方法使用介绍
2013/12/29 Javascript
两种JS实现屏蔽鼠标右键的方法
2020/08/20 Javascript
Js制作点击输入框时默认文字消失的效果
2015/09/05 Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
2016/06/15 Javascript
js 文字超出长度用省略号代替,鼠标悬停并以悬浮框显示实例
2016/12/06 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
利用Javascript获取选择文本所在的句子详解
2017/12/03 Javascript
js数组常用最重要的方法
2018/02/04 Javascript
create-react-app修改为多页面支持的方法
2018/05/17 Javascript
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
Vue动态获取width的方法
2018/08/22 Javascript
Node.js + express实现上传大文件的方法分析【图片、文本文件】
2019/03/14 Javascript
浅析Angular 实现一个repeat指令的方法
2019/07/21 Javascript
python的构建工具setup.py的方法使用示例
2017/10/23 Python
基于python实现在excel中读取与生成随机数写入excel中
2018/01/04 Python
Python内置模块logging用法实例分析
2018/02/12 Python
利用pyinstaller打包exe文件的基本教程
2019/05/02 Python
CSS3 倾斜的网页图片库实例教程
2009/11/14 HTML / CSS
ASOS英国官网:英国在线时装和化妆品零售商
2017/05/19 全球购物
Java面试题:为什么要用Java
2012/05/11 面试题
母亲80寿诞答谢词
2014/01/16 职场文书
优秀信贷员先进事迹
2014/01/31 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
责任书格式范文
2014/07/28 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
体育教师个人工作总结
2015/02/09 职场文书
Python NumPy灰度图像的压缩原理讲解
2021/08/04 Python
梳理总结Python开发中需要摒弃的18个坏习惯
2022/01/22 Python
Vue监视数据的原理详解
2022/02/24 Vue.js
MySQL数据管理操作示例讲解
2022/12/24 MySQL