基于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 相关文章推荐
一个JavaScript继承的实现
Oct 24 Javascript
js取得url地址参数实例
Feb 22 Javascript
JS实现金额转换(将输入的阿拉伯数字)转换成中文的实现代码
Sep 30 Javascript
html的DOM中Event对象onblur事件用法实例
Jan 21 Javascript
ashx文件获取$.ajax()方法发送的数据
May 26 Javascript
Angularjs中使用layDate日期控件示例
Jan 11 Javascript
Bootstrap面板学习使用
Feb 09 Javascript
使用bootstraptable插件实现表格记录的查询、分页、排序操作
Aug 06 Javascript
JS+CSS实现网页加载中的动画效果
Oct 27 Javascript
node.js学习笔记之koa框架和简单爬虫练习
Dec 13 Javascript
小程序getLocation需要在app.json中声明permission字段
Apr 04 Javascript
vue项目中极验验证的使用代码示例
Dec 03 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
PHP截取中文字符串的问题
2006/07/12 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
phpStudy中升级MySQL版本到5.7.17的方法步骤
2017/08/03 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP实现cookie跨域session共享的方法分析
2019/08/23 PHP
js电信网通双线自动选择技巧
2008/11/18 Javascript
javascript css styleFloat和cssFloat
2010/03/15 Javascript
一个简单的js鼠标划过切换效果
2010/06/30 Javascript
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
2013/03/05 Javascript
js触发select onchange事件的小技巧
2014/08/05 Javascript
Jquery的基本对象转换和文档加载用法实例
2015/02/25 Javascript
JS模拟bootstrap下拉菜单效果实例
2016/06/17 Javascript
javascript比较语义化版本号的实现代码
2016/09/09 Javascript
js实现键盘自动打字效果
2016/12/23 Javascript
手机端js和html5刮刮卡效果
2020/09/29 Javascript
seajs中模块依赖的加载处理实例分析
2017/10/10 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
Python 文件操作实现代码
2009/10/07 Python
基于python编写的微博应用
2014/10/17 Python
Python+Pika+RabbitMQ环境部署及实现工作队列的实例教程
2016/06/29 Python
flask入门之表单的实现
2018/07/18 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
使用python绘制二维图形示例
2019/11/22 Python
如何使用python3获取当前路径及os.path.dirname的使用
2019/12/13 Python
Python基于gevent实现高并发代码实例
2020/05/15 Python
python安装sklearn模块的方法详解
2020/11/28 Python
python爬取代理ip的示例
2020/12/18 Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
2021/01/05 Python
利用简洁的图片预加载组件提升html5移动页面的用户体验
2016/03/11 HTML / CSS
Opodo意大利:欧洲市场上领先的在线旅行社
2019/10/24 全球购物
临床医学专业学生的自我评价分享
2013/11/21 职场文书
公务员培训自我鉴定
2014/02/01 职场文书
2014年会策划方案
2014/05/11 职场文书
2019年“红色之旅”心得体会1000字(3篇)
2019/09/27 职场文书
SQL SERVER中常用日期函数的具体使用
2021/04/08 SQL Server