基于Vue的事件响应式进度条组件
写在前面
找了很多Vue 进度条组件!,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理。即使做好了,将来需要修改外观,又是一番折腾。
基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处。
事件响应式进度条的应用场景主要是自定义video播放器的进度条。
效果图
以上就是可以利用本组件实现的一些效果,他们都能响应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:进度条高度,传像素值
事件
- pbar-drag: 拖动进度条时触发,回传value值和百分比值
- pbar-drag: 点击进度条某一位置时触发,回传value值和百分比值
最后
如果本文对你有帮助,请不要吝啬手中的点赞哟。
编程贵在实践,赶紧行动起来吧!
关于作者
原文地址:https://segmentfault.com/a/1190000013123304
基于Vue的事件响应式进度条组件的更多相关文章
- 基于 Vue + Element 的响应式后台模板
项目地址 https://github.com/caochangkui/vue-element-responsive-demo 主要功能 响应式侧边栏 面包屑导航(结合router.js) 路由动效 ...
- 一款基于jquery带百分比的响应式进度加载条
今天要给大家带来一款基于jquery带百分比的响应式进度加载条.这款加载条非常漂亮,而且带有进度的百度比,且在不同的百分比用的是不同的颜色.而且这款加载条采用了响应式设计,在不同的分辨率的显示器下完美 ...
- Vue 及框架响应式系统原理
个人bolg地址 全局概览 Vue运行内部运行机制 总览图: 初始化及挂载 在 new Vue()之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周期. ...
- vue原理探索--响应式系统
Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是「响应式系统」. 首先看一下 Object.defi ...
- Vue 2.0 与 Vue 3.0 响应式原理比较
Vue 2.0 的响应式是基于Object.defineProperty实现的 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 prop ...
- Bootstrap组件之响应式导航条
响应式导航条:在PC和平板中默认要显示所有的内容:但在手机中导航条中默认只显示“LOGO/Brand”,以及一个“菜单折叠展开按钮”,只有单击折叠按钮后才显示所有的菜单项. 基础class: .nav ...
- CSS3时钟式进度条
CSS3时钟式进度条,加载完成时生成一个圆,数字慢慢变成100,适时的显示加载进度.友情提醒,如果预览时网页左下角提示错误,刷新一下就可以看到效果了:实际使用中不会出现这样的问题. <!DOCT ...
- CSS3+Js制作的一款响应式导航条
今天制作了一个响应式导航条,能够自动随着不同的屏幕分辨率或浏览器窗口大小的不同而改变导航条的样式,这里主要用到的就是CSS3的Media Query.具体可以查看浅谈响应式布局这篇文章,这里就不花费大 ...
- vue 的进度条组件
先看效果: 要想实现如上图的,进度跳效果,有两种方式,首先介绍第一种: 1.自己用 div 写一个,代码如下 <template> <div class="mfc-slid ...
随机推荐
- pl/sql developer 自动输入替换 光标自动定位
pl/sql developer 自动输入替换 工具->首选项->用户界面->编辑器->自动替换,自己定义一些规则,然后输入key,点击tab或者空格,就可以进行替换了: SL ...
- FZU 1851 组合数
给你两个数n和m,然后让你求组合数C(n,m)中的质因子的个数. 这里用到的一个定理:判断阶乘n!中的质因子 i 的个数的方法---f(n!)=n/i+n/i^2+n/i^3+.....n/i^m ( ...
- 【转】selenium自动化测试环境搭建
转:http://blog.csdn.net/mao1059568684/article/details/17347853 第一步 安装JDK JDk1.7. 下载地址:http://www.orac ...
- ArcGIS教程:加权总和
摘要 通过将栅格各自乘以指定的权重并合计在一起来叠加多个栅格. 插图 插图中,像元值与其权重因子相乘.两者所得结果相加创建输出栅格.以左上角像元为例.两个输入的值变为 (2.2 * 0.75) = 1 ...
- 0x59 单调队列优化DP
倍增DP太难啦心情好再回去做 poj1821 先让工匠按s排序,f[i][j]表示枚举到第i个工匠涂了j个木板(注意第j个木板不一定要涂) 那么f[i][j]可以直接继承f[i-1][j]和f[i][ ...
- hihoCoder-1828 2018亚洲区预选赛北京赛站网络赛 A.Saving Tang Monk II BFS
题面 题意:N*M的网格图里,有起点S,终点T,然后有'.'表示一般房间,'#'表示毒气房间,进入毒气房间要消耗一个氧气瓶,而且要多停留一分钟,'B'表示放氧气瓶的房间,每次进入可以获得一个氧气瓶,最 ...
- js设计模式-组合模式
组合模式是一种专为创建web上的动态用户界面而量身定制的模式.使用这种模式,可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更容易维护,而那些复杂行为则被委托给各个对象. ...
- NOIP2013 D1T3 货车运输
[NOIP2013T3]货车运输 背景 noip2013day1 描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重 量限制,简称限重.现在有 q 辆货 ...
- NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
思路: Kruskal求最大生成树+倍增LCA // by SiriusRen #include <cstdio> #include <cstring> #include &l ...
- git window端工具之sourcetree使用
https://www.jianshu.com/p/3478e2a214a1