基于element-ui组件手动实现单选和上传功能


Posted in Javascript onDecember 06, 2018

前言

在用户使用过程中提出一键导入的功能,需求如下:点击导入按钮显示提示框,然后是单选框以及上传按钮。pc端常使用element-ui组件,但是这个项目是vue1的老项目,并且没有element-ui组件。所以需要自己动手实现单选功能和上传功能。

基于element-ui组件手动实现单选和上传功能 

radio 属性及方法

name: 用于定义同一类型的 radio 同一 name 的 radio 只能选中一个(单选实现)

  • id: 用于和 label 标签关联起来 实现点击 label 标签内的元素也能选中 radio
  • value:单选按钮的值,选中某个单选按钮相当于拿到 value 值 tip:用于识别组中的哪个单选按钮被选中。
  • checked 用于设置默认选中的 radio
  • v-model 创建双向数据绑定。 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。
// html
 <div v-for="day in weekSelectList"
 :key="day.id"
 class="select__day">
 <input type="radio"
  name="week"
  :id="day.label"
  :value="day.value"
  v-model="selectedDay">
 <label :for="day.label">{{day.label}}({{day.value}})</label>
 </div>
// 暂定的数据
data(){
 return {
 weekSelectList: [
  { label: '周一', value: '2018-12', id: 1 },
  { label: '周二', value: '2018-13', id: 2 },
  { label: '周三', value: '2018-14', id: 3 },
  { label: '周四', value: '2018-15', id: 4 },
  { label: '周五', value: '2018-16', id: 5 }
 ]
 },
 selectedDay: '2018-12',
}

通过 v-model 绑定 selectedDay,匹配到相同的值会将该 radio 选中,当改变 radio 的选择,selectedDay 也会动态的变更成选中的 radio 的 value

上传文件

属性

accept 属性接受一个(多个值时)逗号分隔的字符串 如:accept="image/png, image/jpeg"

  • id
  • name
  • 注意:accept 属性并不会验证选中文件的类型只是在用户浏览时只显示指定文件类型

缺点

  1. 在未上传文件时,显示"未选择文件",用户界面不友好,不可配置
  2. 同一个文件名即使内容改变了,重新上传也不会触发 change 事件
  3. 用户如果在上传过程中点击了“取消”,已经上传的文件会被移除

解决方式

 

<div class="upload__button"
 :class="{'upload__button--uploaded':isUploaded}"
 @click="onUploadClick">点击上传</div>
 <input type="file"
 class="upload__file"
 v-el:upload
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
 @change="onFileChange" />
methods:{
 onUploadClick() {
 if (!this.isUploaded) {
  this.$els.upload.click()
 }
 },
 onFileChange(e) {
 const file = e.target.files[0]
 if (file === undefined) {
 return
 }
 this.fileName = file.name
 const result = /[xls|xlsx]$/.test(this.fileName)
 if (result) {
  this.isUploaded = true
  this.showAlert('上传成功')
  this.$els.upload.value = null
 } else {
  this.showAlert('文件格式错误,请确认后重试。')
 }
 },
}

当点击上传按钮触发 onUploadClick 事件后,获取到 upload 绑定的 DOM (由于是老的项目使用的是$els,vue2 使用 ref)手动触发 click 事件并且可以在change事件中默认接收一个文件信息对象其中target.files[0]包含文件的更多信息,如下图:

基于element-ui组件手动实现单选和上传功能 

判断文件类型

可以看到 change 事件的返回值包含着文件属性,这里我们需要判断是文件名是否为 excel,使用正则的 test 方法。

重置change事件

在最后 this.$refs.uploadFile.value = null; 移除文件,可以保证上传同样的文件时,也会触发 change 事件

优化样式

至此关于表单方面的功能都已经实现了,由于原始的radio样式比较丑,而且不能更改。下面我们就想办法将它做的漂亮些。

// template
 <label v-for="(item,index) in radioList"
  :key="item.value"
  :for="item.linkLabel"
  :accesskey="index">
  <span class="content__input">
   <span class="radio__replace"
   :class="{'radio__replace--checked':selectedRadio===item.value,'radio__replace--disable':item.isDisabled}">
   </span>
   <input v-model="selectedRadio"
   type="radio"
   class="radio__button"
   name="radio"
   :id="item.linkLabel"
   :tabindex="index"
   :value="item.value"
   :disabled="item.isDisabled"
   @focus="item.isFocus = true"
   @blur="item.isFocus = false" />
  </span>
  <span class="content__text">{{item.label}}</span>
  </label>
// data
 data() {
 return {
  radioList: [
  {
   linkLabel: 'label1',
   value: '1',
   isDisabled: false,
   isFocus: false,
   label: '标签1'
  },
  {
   linkLabel: 'label2',
   value: '2',
   isDisabled: false,
   isFocus: false,
   label: '标签2'
  },
  {
   linkLabel: 'label3',
   value: '3',
   isDisabled: true,
   isFocus: false,
   label: '标签3'
  }
  ],
  selectedRadio: '1'
 }
  • 这里使用遍历的方式在data中定义多个radio,在前面我们讲到过radio的基本用法,使用label的for属性和input的for属性实现关联起来。(这里我将input放在label内,这样点击整个label都会选中,没有label和radio元素之间的间隙)。
  • name相同的radio会实现单选效果,tabindex代表使用"Tab"键的遍历顺序 ,value是选中时v-model绑定的selectedRadio也就会跟着变更
  • 实现个性化样式的关键在于结构就是用一个类名content__input标签将类名radio__replace和radio包起来。设置定位层级(相当于radio被覆盖了,然而只要点击到labelradio就会被选中)
  • 通过selectedRadio选中的值和当前radio值做对比,以及isDisabled这些Boolean值来动态绑定class实现我们自定义的radio样式切换

效果如下:

基于element-ui组件手动实现单选和上传功能 

其实radio__replace类名对应的标签就是我们自定义的radio,其中的白色原点是通过伪类生成的css代码放在最后,感兴趣可以看下

伪类样式修改

如果想通过类名来改变白色原点的样式,可以通过权重来改变。如下通过isShow来给外层添加test类名 而起始的时候设置的权重为两层,之后添加一层可以起到修改样式的效果。(ps:伪类不能通过预先设定好的类名来修改样式)

例子代码如下:

<div :class="{test:isShow}"
  @click="onRedClick">
  <div class="text__item"></div>
 </div>
.text__item {
 &:after {
 content: '';
 width: 30px;
 height: 30px;
 background-color: #f00;
 position: absolute;
 bottom: 20px;
 }
}
.test {
 .text__item {
 &:after {
  background-color: #ff0;
 }
 }
}
// css
 .radio {
  &__replace {
   border: 1px solid #dcdfe6;
   border-radius: 100%;
   width: 14px;
   height: 14px;
   background-color: #fff;
   position: relative;
   cursor: pointer;
   display: inline-block;
   box-sizing: border-box;
   z-index: 999;
   transition: 0.15s ease-in;
   &--checked {
   border-color: #409eff;
   background-color: #409eff;
   }
   &--disable {
   cursor: not-allowed;
   }
   &:after {
   width: 4px;
   height: 4px;
   border-radius: 100%;
   background-color: #fff;
   content: '';
   position: absolute;
   left: 50%;
   top: 50%;
   transform: translate(-50%, -50%);
   }
  }
  &__button {
   opacity: 0;
   outline: none;
   position: absolute;
   z-index: -1;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   margin: 0;
  }
  }

总结

  1. 介绍了radio基本属性,使用案例并优化了radio的样式
  2. 原始上传文件元素的缺点以及改善方法

以上所述是小编给大家介绍的基于element-ui组件手动实现单选和上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Underscore.js 的模板功能介绍与应用
Dec 24 Javascript
捕获键盘事件(且兼容各浏览器)
Jul 03 Javascript
JavaScript面向对象的实现方法小结
Apr 14 Javascript
JavaScript获取客户端IP的方法(新方法)
Mar 11 Javascript
微信小程序 for 循环详解
Oct 09 Javascript
浅析script标签中的defer与async属性
Nov 30 Javascript
微信小程序 小程序制作及动画(animation样式)详解
Jan 06 Javascript
jQuery DateTimePicker 日期和时间插件示例
Jan 22 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
Feb 09 Javascript
jQuery实现的自定义轮播图功能详解
Dec 28 jQuery
Node.js Event Loop各阶段讲解
Mar 08 Javascript
JavaScript正则表达式验证登录实例
Mar 18 Javascript
JavaScript 中 JSON.parse 函数 和 JSON.stringify 函数
Dec 05 #Javascript
在Vant的基础上实现添加表单验证框架的方法示例
Dec 05 #Javascript
在Vant的基础上封装下拉日期控件的代码示例
Dec 05 #Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
Dec 05 #Javascript
微信小程序实现图片滚动效果示例
Dec 05 #Javascript
详解vue中的computed的this指向问题
Dec 05 #Javascript
使用rollup打包JS的方法步骤
Dec 05 #Javascript
You might like
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
PHP字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
2011/11/10 PHP
Codeigniter的一些优秀特性总结
2015/01/21 PHP
PHP+JQuery+Ajax实现分页方法详解
2016/08/06 PHP
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
基于Require.js使用方法(总结)
2017/10/26 Javascript
vue+swiper实现组件化开发的实例代码
2017/10/26 Javascript
Angular实现下拉框模糊查询功能示例
2018/01/03 Javascript
Vue.js单向绑定和双向绑定实例分析
2018/08/14 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
python实现基于两张图片生成圆角图标效果的方法
2015/03/26 Python
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
详细介绍Python的鸭子类型
2016/09/12 Python
Python读取Json字典写入Excel表格的方法
2018/01/03 Python
浅谈Python 敏感词过滤的实现
2019/08/15 Python
用sqlalchemy构建Django连接池的实例
2019/08/29 Python
python误差棒图errorbar()函数实例解析
2020/02/11 Python
使用python批量修改XML文件中图像的depth值
2020/07/22 Python
解决python打开https出现certificate verify failed的问题
2020/09/03 Python
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
初中考试作弊检讨书
2014/02/01 职场文书
发展部经理职责规定
2014/02/22 职场文书
厕所文明标语
2014/06/11 职场文书
小学生环保标语
2014/06/13 职场文书
2014年控辍保学工作总结
2014/12/08 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
奖金申请报告模板
2015/05/15 职场文书
博士论文答辩开场白
2015/06/01 职场文书
新学期开学标语2015
2015/07/16 职场文书
表彰大会新闻稿
2015/07/17 职场文书
干部作风纪律整顿心得体会
2016/01/23 职场文书
Mac环境Nginx配置和访问本地静态资源的实现
2021/03/31 Servers
Python可视化学习之seaborn调色盘
2022/02/24 Python
mysql中数据库覆盖导入的几种方式总结
2022/03/25 MySQL