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 设计模式学习 Factory
Jul 29 Javascript
从jQuery.camelCase()学习string.replace() 函数学习
Sep 13 Javascript
javascript判断ie浏览器6/7版本加载不同样式表的实现代码
Dec 26 Javascript
javascript获取url上某个参数的方法
Nov 08 Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
Mar 29 Javascript
JS中JSON对象和String之间的互转及处理技巧
Apr 06 Javascript
Vue和Bootstrap的整合思路详解
Jun 30 Javascript
将jquery.qqFace.js表情转换成微信的字符码
Dec 01 jQuery
JS实现为动态创建的元素添加事件操作示例
Mar 17 Javascript
微信小程序工具函数封装
Oct 28 Javascript
jQuery实现评论模块
Aug 19 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
不用数据库的多用户文件自由上传投票系统(2)
2006/10/09 PHP
用php或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
php中用date函数获取当前时间有误的解决办法
2013/08/02 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
同一个表单 根据要求递交到不同页面的实现方法小结
2009/08/05 Javascript
JavaScript 弹出窗体点击按钮返回选择数据的实现
2010/04/01 Javascript
js 回车提交表单两种实现方法
2012/12/31 Javascript
JS.GetAllChild(element,deep,condition)使用介绍
2013/09/21 Javascript
jQuery.holdReady()使用方法
2014/05/20 Javascript
jQuery中val()方法用法实例
2014/12/25 Javascript
推荐10 款 SVG 动画的 JavaScript 库
2015/03/24 Javascript
js获取当前日期时间及其它操作汇总
2015/04/17 Javascript
学习javascript文件加载优化
2016/02/19 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
2016/03/07 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
Web打印解决方案之普通报表打印功能
2016/08/29 Javascript
ES6中的rest参数与扩展运算符详解
2017/07/18 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
vue路由传参的基本实现方式小结【三种方式】
2020/02/05 Javascript
在vue中封装的弹窗组件使用队列模式实现方法
2020/07/23 Javascript
Python实现PS滤镜中马赛克效果示例
2018/01/20 Python
python自动重试第三方包retrying模块的方法
2018/04/24 Python
python实现通过队列完成进程间的多任务功能示例
2019/10/28 Python
Python+redis通过限流保护高并发系统
2020/04/15 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
2020/06/22 Python
大学生职业生涯规划范文
2014/01/22 职场文书
销售主管岗位职责范本
2014/02/14 职场文书
小班开学寄语
2014/04/04 职场文书
品质口号大全
2014/06/17 职场文书
2014年社区重阳节活动策划方案
2014/09/16 职场文书
员工工作及收入证明
2014/10/28 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
暂住证明怎么写
2015/06/19 职场文书
WIN10使用IIS部署ftp服务器详细教程
2022/08/05 Servers