基于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 相关文章推荐
JS 文件本身编码转换 图文教程
Oct 12 Javascript
关于hashchangebroker和statehashable的补充文档
Aug 08 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
May 21 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
Jun 11 Javascript
JQuery实现动态表格点击按钮表格增加一行
Aug 24 Javascript
多个checkbox被选中时如何判断是否有自己想要的
Sep 22 Javascript
jquery实现的判断倒计时是否结束代码
Feb 05 Javascript
js实现3D图片环展示效果
Mar 09 Javascript
Angular2 父子组件通信方式的示例
Jan 29 Javascript
微信小程序自定义底部弹出框
Nov 16 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
vue+springboot实现登录验证码
May 27 Vue.js
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
ThinkPHP 表单自动验证运用示例
2014/10/13 PHP
PHP实现根据图片色界在不同位置加水印的方法
2015/08/08 PHP
PHP检测用户是否关闭浏览器的方法
2016/02/14 PHP
PHP list() 将数组中的值赋给变量的简单实例
2016/06/13 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
用Javascript实现Windows任务管理器的代码
2012/03/27 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
JavaScript动态操作表格实例(添加,删除行,列及单元格)
2013/11/25 Javascript
html文本框提示效果的示例代码
2014/06/28 Javascript
用js读、写、删除Cookie代码续篇
2014/12/03 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
Bootstrap每天必学之导航组件
2016/04/25 Javascript
AngularJS中的包含详细介绍及实现示例
2016/07/28 Javascript
JS获取和修改元素样式的实例代码
2016/08/06 Javascript
Javascript中apply、call、bind的巧妙使用
2016/08/18 Javascript
js防阻塞加载的实现方法
2016/09/09 Javascript
Angular多选、全选、批量选择操作实例代码
2017/03/10 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
element实现合并单元格通用方法
2019/11/13 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
python读取注册表中值的方法
2013/04/08 Python
python的scikit-learn将特征转成one-hot特征的方法
2018/07/10 Python
django 类视图的使用方法详解
2019/07/24 Python
opencv 图像加法与图像融合的实现代码
2020/07/08 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
matplotlib事件处理基础(事件绑定、事件属性)
2021/02/03 Python
ALDO加拿大官网:加拿大女鞋品牌
2018/12/22 全球购物
办公室人员先进事迹
2014/01/27 职场文书
会计专业自荐信
2014/06/03 职场文书
2014年党员自我剖析材料
2014/10/07 职场文书
党委书记个人检查对照材料思想汇报
2014/10/11 职场文书
心理学培训心得体会
2016/01/22 职场文书
2016学习医德医风心得体会
2016/01/25 职场文书
创业计划书之农家乐
2019/10/09 职场文书