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 相关文章推荐
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
Nov 03 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
Feb 13 Javascript
js写的方法实现上传图片之后查看大图
Mar 05 Javascript
js操作数组函数实例小结
Dec 10 Javascript
javascript函数命名的三种方式及区别介绍
Mar 22 Javascript
angularjs 源码解析之injector
Aug 22 Javascript
Vue实现双向绑定的方法
Dec 22 Javascript
canvas实现爱心和彩虹雨效果
Mar 09 Javascript
React利用插件和不用插件实现双向绑定的方法详解
Jul 03 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
Nov 28 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧不动,右侧滑动)
Jan 23 Javascript
vue使用keep-alive实现组件切换时保存原组件数据方法
Oct 30 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 中使用ajax时一些常见错误总结整理
2017/02/27 PHP
cloudgamer出品ImageZoom 图片放大效果
2010/04/01 Javascript
Extjs4.0设置Ext.data.Store传参的请求方式(默认为GET)
2013/04/02 Javascript
JQuery给元素添加/删除节点比如select
2013/04/02 Javascript
js图片延迟加载的实现方法及思路
2013/07/22 Javascript
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
使用Javascript写的2048小游戏
2015/11/25 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
Ext JS 实现建议词模糊动态搜索功能
2017/05/13 Javascript
JavaScript实现QQ聊天消息展示和评论提交功能
2017/05/22 Javascript
鼠标拖动改变DIV等网页元素的大小的实现方法
2017/07/06 Javascript
bootstrap可编辑下拉框jquery.editable-select
2017/10/12 jQuery
vue+element-ui动态生成多级表头的方法
2018/08/28 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
2020/03/02 Javascript
vue动态设置路由权限的主要思路
2021/01/13 Vue.js
Python中asyncore的用法实例
2014/09/29 Python
用Python从零实现贝叶斯分类器的机器学习的教程
2015/03/31 Python
Python类的用法实例浅析
2015/05/27 Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
2018/02/05 Python
python实现多线程网页下载器
2018/04/15 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
python定时任务 sched模块用法实例
2019/11/04 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
Kmeans均值聚类算法原理以及Python如何实现
2020/09/26 Python
5分钟实现Canvas鼠标跟随动画背景
2019/11/18 HTML / CSS
佳能英国官方网站:Canon UK
2017/08/08 全球购物
美国流行背包品牌:JanSport(杰斯伯)
2018/03/02 全球购物
违反校纪校规检讨书
2014/02/15 职场文书
英语专业求职信
2014/07/08 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
一个独生女的故事观后感
2015/06/04 职场文书
公司转让协议书
2016/03/19 职场文书
导游词之四川武侯祠
2019/10/21 职场文书
浅谈Redis的几个过期策略
2021/05/27 Redis
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏