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计算两个时间之间天数差的实例代码
Nov 19 Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
Feb 24 Javascript
现如今最流行的JavaScript代码规范
Mar 08 Javascript
require.js配合插件text.js实现最简单的单页应用程序
Jul 12 Javascript
javascript实现根据汉字获取简拼
Sep 25 Javascript
bootstrap警告框使用方法解析
Jan 13 Javascript
JS如何实现在页面上快速定位(锚点跳转问题)
Aug 14 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
vue中v-for加载本地静态图片方法
Mar 03 Javascript
原生js封装的ajax方法示例
Aug 02 Javascript
详解javascript 变量提升(Hoisting)
Mar 12 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
Apr 08 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数组函数
2008/08/18 PHP
php的ddos攻击解决方法
2015/01/08 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
php opendir()列出目录下所有文件的实例代码
2016/10/02 PHP
PHP经典实用正则表达式小结
2017/05/04 PHP
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
通过伪协议解决父页面与iframe页面通信的问题
2015/04/05 Javascript
jQuery层动画定位滑动效果的方法
2015/04/30 Javascript
jquery实现华丽的可折角广告代码
2015/09/02 Javascript
Js制作点击输入框时默认文字消失的效果
2015/09/05 Javascript
jQuery获取父元素及父节点的方法小结
2016/04/14 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
三种带箭头提示框总结实例
2016/06/14 Javascript
WEB 前端开发中防治重复提交的实现方法
2016/10/26 Javascript
Angular 常用指令实例总结整理
2016/12/13 Javascript
Vue2.0实现购物车功能
2017/06/05 Javascript
JS判断时间段的实现代码
2017/06/14 Javascript
本地搭建微信小程序服务器的实现方法
2017/10/27 Javascript
详解Angular5路由传值方式及其相关问题
2018/04/28 Javascript
vue使用rem实现 移动端屏幕适配
2018/09/26 Javascript
JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例
2018/12/14 Javascript
Python中无限元素列表的实现方法
2014/08/18 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
2019/08/23 Python
pytorch GAN伪造手写体mnist数据集方式
2020/01/10 Python
python 使用递归实现打印一个数字的每一位示例
2020/02/27 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
2020/06/01 Python
django使用graphql的实例
2020/09/02 Python
英国虚拟主机服务商:eUKhost
2016/08/16 全球购物
北美三大旅游网站之一:Travelocity加拿大
2016/08/20 全球购物
师范生教师实习自我鉴定
2013/09/27 职场文书
农村婚庆司仪主持词
2014/03/15 职场文书
2014年安置帮教工作总结
2014/12/11 职场文书
迎国庆主题班会
2015/08/17 职场文书
在Centos 8.0中安装Redis服务器的教程详解
2022/03/21 Redis
netty 实现tomcat的示例代码
2022/06/05 Servers