Vue的事件响应式进度条组件实例详解


Posted in Javascript onFebruary 04, 2018

写在前面

找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理。即使做好了,将来需要修改外观,又是一番折腾。

基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处。

效果图

Vue的事件响应式进度条组件实例详解

以上就是可以利用本组件实现的一些效果,他们都能响应input和change两种事件。

首先是模板部分

认真看一下上图,怎么构造HTML模板还是需要一番考虑的,我也是改了好几次,最后定的这个结构。首先有一层外包div就不说了。然后外包div下面就一个class = 'progress'的div,这个div内部的div是表示进度条已划过部分(class="left"),class="left"这个div内部又包含一个表示div来表示我们可以拖动的滑块小球。

说一下好处,这样的结构,做出来的样式,在页面检查元素的时候,能够清晰看到每个div和页面上展示的部分是重合的。

如果你的进度条 表示整个长度的div、表示左半部分的div、表示滑块的div不是我这种嵌套结构,而是兄弟节点关系,你就得用样式做相对定位,让后两个兄弟节点上移,这样,检查元素的时候,进度条下面的其他组件的盒子就会浸透到进度条的区域。虽然用户不会检查元素,但是时间久了之后也不方便程序员自己观察,不是吗。

也就是说,我们都希望HTML结构表达的元素和检查元素的时候显示的每个元素的占位是一致的。这也算是对你的HTML结构是否构造合理的一个评价指标。

<template>
 <div class="progress-wrapper" :style="wrapStyle">
  <div class="progress" @mousedown="mousedownHandler" @mouseover="mouseoverHandler"
    @mousemove="mousemoveHandler" @mouseup="mouseupHandler" :style="pBarStyle">
   <div class="left" :style="leftStyle">
    <div class="ball" :style="ballStyle"></div>
   </div>
   <slot></slot>
  </div>
 </div>
</template>

js部分

对现在就有需求使用这个带事件的进度条的同学来说,看看这部分,可以帮助你自己修改、完善它。

而对于想要先试用该组件的同学,则可以先不看这部分,等你用到发现该组件功能不足的时候,再看这部分代码也不迟。

export default {
  name: 'ProgressBar',
  props: {
   leftBg: String,
   bgc: String,
   ballBgc: String,
   height: String,
   width: String,
   max: {
    type: Number,
    default: 100,
   },
   min: {
    type: Number,
    default: 0,
   },
   value: {
    type: Number,
    default: 36,
   },
  },
  data: function () {
   return {
    pValue: this.value,
    pMax: this.max,
    pMin: this.min,
    wrapStyle: {
     'width': this.width,
    },
    pBarStyle: {
     'backgroundColor': this.bgc,
     'height': this.height,
    },
    leftStyle: {
     'width': this.progressPercent + '%',
     'background': this.leftBg,
     'height': this.height,
    },
    ballStyle: {
     'backgroundColor': this.ballBgc,
     'height': this.height,
     'width': this.height,
     'borderRadius': parseInt(this.height) / 2 + 'px',
     'right': - parseInt(this.height) / 2 + 'px',
    },
    // 标记是否按下鼠标
    isMouseDownOnBall: false,
   }
  },
  computed: {
   progressPercent(){
    return (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100;
   },
   progressElement(){
    return this.$el.getElementsByClassName('progress')[0];
   },
  },
  methods: {
   mousedownHandler(e){
    if(e.which === 1){
     this.isMouseDownOnBall = true;
    }
   },
   mousemoveHandler(e){
    if(this.isMouseDownOnBall === true){
     // 修改进度条本身
     let decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
     let percent = decimal * 100;
     this.leftStyle.width = percent + '%';
     // 修改value
     this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
     this.$emit('pbar-drag', this.pValue, percent);
    }
   },
   mouseupHandler(e){
    if(this.isMouseDownOnBall){
     // 修改进度条本身
     let decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
     let percent = decimal * 100;
     this.leftStyle.width = percent + '%';
     // 修改value
     this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
     this.$emit('pbar-seek', this.pValue, percent);
     this.isMouseDownOnBall = false;
    }
   },
   mouseoverHandler(e){
    // 没有按左键进入进度条
    if(e.which === 0){
     this.isMouseDownOnBall = false;
    }
   }
  },
  watch: {
   max(cur, old){
    this.pMax = cur;
   },
   min(cur, old){
    this.pMin = cur;
   },
   value(cur, old){
    this.pValue = cur;
   },
   progressPercent(cur, old){
    this.leftStyle.width = cur + '%';
   }
  },
  mounted(){
   // 数据验证
   if(this.max < this.min){
    console.error("max can't less than min !");
   }
   // 初始百分比
   this.leftStyle.width = (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100 + '%';
  },
 }

安装、使用

地址

代码库地址在GitHub

安装、使用

npm install vue-draggable-progressbar --save
import progressBar from 'vue-draggable-progressbar'

用例:

<progress-bar ref="aa"></progress-bar>
<progress-bar width="40%" leftBg="greenyellow" bgc="#ccc" ballBgc="red"></progress-bar>
<progress-bar width="60%" leftBg="linear-gradient(to right, yellow, pink)" bgc="#ccc" ballBgc="red"></progress-bar>
<progress-bar width="80%" leftBg="yellow" bgc="#ccc" ballBgc="red" height="30px"></progress-bar>
<progress-bar leftBg="greenyellow" bgc="#ccc" ballBgc="rgba(255,0,0,0.2)" height="40px"></progress-bar>
<progress-bar leftBg="greenyellow" bgc="#ccc" ballBgc="red" :max="max" :value="value" :min="min"
    @pbar-drag="drag" @pbar-seek="seek"></progress-bar>

组件props

  • leftBg:进度条已划过部分背景色
  • bgc:进度条还未划过部分背景色
  • ballBgc:滑块背景色
  • width:进度条占父组件的宽度百分比,传百分比数值
  • height:进度条高度,传像素值
  • max:进度条最大值
  • min:最小值
  • value:当前值

事件

  • pbar-drag: 拖动进度条时触发,回传value值和百分比值
  • pbar-drag: 点击进度条某一位置时触发,回传value值和百分比值

总结

以上所述是小编给大家介绍的Vue的事件响应式进度条组件实例详解,希望对大家有所帮助,如果大家哟任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
利用JQuery+EasyDrag 实现弹出可拖动的Div,同时向Div传值,然后返回Div选中的值
Oct 24 Javascript
IE6下JS动态设置图片src地址问题
Jan 08 Javascript
几个比较实用的JavaScript 测试及效验工具
Apr 18 Javascript
JavaScript创建类/对象的几种方式概述及实例
May 06 Javascript
有效提高JavaScript执行效率的几点知识
Jan 31 Javascript
jQuery无刷新分页完整实例代码
Oct 27 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
Sep 12 Javascript
requireJS模块化实现返回顶部功能的方法详解
Oct 16 Javascript
解决vue打包后vendor.js文件过大问题
Jul 03 Javascript
小程序跳转H5页面的方法步骤
Mar 06 Javascript
详解Vue中的MVVM原理和实现方法
Jul 15 Javascript
js实现表格单列按字母排序
Aug 12 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
Feb 04 #Javascript
Vue的土著指令和自定义指令实例详解
Feb 04 #Javascript
彻底理解js面向对象之继承
Feb 04 #Javascript
vue里面父组件修改子组件样式的方法
Feb 03 #Javascript
vue中element组件样式修改无效的解决方法
Feb 03 #Javascript
浅谈vue中改elementUI默认样式引发的static与assets的区别
Feb 03 #Javascript
Vue修改mint-ui默认样式的方法
Feb 03 #Javascript
You might like
php学习笔记之 函数声明(二)
2011/06/09 PHP
php 模拟get_headers函数的代码示例
2013/04/27 PHP
PHP传参之传值与传址的区别
2015/04/24 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
PHP如何解决微信文章图片防盗链
2020/12/09 PHP
JavaScript 编程引入命名空间的方法
2007/06/29 Javascript
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
原生Javascript封装的一个AJAX函数分享
2014/10/11 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
React.js入门实例教程之创建hello world 的5种方式
2016/05/11 Javascript
如何检测JavaScript的各种类型
2016/07/30 Javascript
详解如何使用router-link对象方式传递参数?
2019/05/02 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
[43:51]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS Secret
2018/03/31 DOTA
Python中几种操作字符串的方法的介绍
2015/04/09 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
python中私有函数调用方法解密
2016/04/29 Python
Python实现的选择排序算法示例
2017/11/29 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
Python开发的十个小贴士和技巧及长常犯错误
2018/09/27 Python
Django组件之cookie与session的使用方法
2019/01/10 Python
python安装scipy的步骤解析
2019/09/28 Python
python 实现仿微信聊天时间格式化显示的代码
2020/04/17 Python
在canvas上实现元素图片镜像翻转动画效果的方法
2018/03/20 HTML / CSS
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
Spartoo葡萄牙鞋类网站:线上销售鞋履与时尚配饰
2017/01/11 全球购物
Aerosoles爱柔仕官网:美国舒软女鞋品牌
2017/07/17 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
年会搞笑主持词串词
2014/03/24 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
离婚协议书怎么写(范本参考)
2014/09/30 职场文书
教师三严三实心得体会
2014/10/11 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
2014年纪检部工作总结
2014/11/12 职场文书
关于远足的感想
2015/08/10 职场文书