基于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 相关文章推荐
c#和Javascript操作同一json对象的实现代码
Jan 17 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
Sep 03 Javascript
javascript中Array()数组函数详解
Aug 23 Javascript
JS基于构造函数实现的菜单滑动显隐效果【测试可用】
Jun 21 Javascript
js实现文字超出部分用省略号代替实例代码
Sep 01 Javascript
jquery实现图片放大点击切换
Jun 06 jQuery
bootstrap table支持高度百分比的实例代码
Feb 28 Javascript
Vue.js子组件向父组件通信的方法实例代码详解
Dec 10 Javascript
jQuery实现动态加载(按需加载)javascript文件的方法分析
May 31 jQuery
layui添加动态菜单与选项卡
Jul 26 Javascript
基于JS判断对象是否是数组
Jan 10 Javascript
Node.js设置定时任务之node-schedule模块的使用详解
Apr 28 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入门的学习方法
2007/01/02 PHP
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
php求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
php字符串过滤strip_tags()函数用法实例分析
2019/06/24 PHP
php判断IP地址是否在多个IP段内
2020/08/18 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
JavaScript 继承详解(二)
2009/07/13 Javascript
JS 事件绑定函数代码
2010/04/28 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
使用Jquery实现每日签到功能
2015/04/03 Javascript
javascript Slip.js实现整屏滑动的手机网页
2015/11/25 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
JavaScript中点击事件的写法
2016/06/28 Javascript
BootStrap Typeahead自动补全插件实例代码
2016/08/10 Javascript
vue货币过滤器的实现方法
2017/04/01 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
快速解决Vue、element-ui的resetFields()方法重置表单无效的问题
2020/08/12 Javascript
JavaScript实现随机点名小程序
2020/10/29 Javascript
如何在JavaScript中正确处理变量
2020/12/25 Javascript
[01:45]DOTA2新英雄“神谕者”全方位展示
2014/11/21 DOTA
python检查序列seq是否含有aset中项的方法
2015/06/30 Python
python如何对实例属性进行类型检查
2018/03/20 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
pytorch数据预处理错误的解决
2020/02/20 Python
OpenCV4.1.0+VS2017环境配置的方法步骤
2020/07/09 Python
HTML5之web workers_动力节点Java学院整理
2017/07/17 HTML / CSS
HTML5实现的图片无限加载的瀑布流效果另带边框圆角阴影
2014/03/07 HTML / CSS
HTML5中的拖放实现详解
2017/08/23 HTML / CSS
密封类可以有虚函数吗
2014/08/11 面试题
Delphi笔试题
2016/11/14 面试题
夜大毕业生自我评价分享
2013/11/10 职场文书
银行简历自我评价
2014/02/11 职场文书
党的群众路线调研报告
2014/11/03 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers