前端之家收集整理的这篇文章主要介绍了
Vue的事件响应式进度条组件实例详解,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
写在前面
找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理。即使做好了,将来需要修改外观,又是一番折腾。
基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处。
效果图
以上就是可以利用本组件实现的一些效果,他们都能响应input和change两种事件。
首先是模板部分
认真看一下上图,怎么构造HTML模板还是需要一番考虑的,我也是改了好几次,最后定的这个结构。首先有一层外包div就不说了。然后外包div下面就一个class = 'progress'的div,这个div内部的div是表示进度条已划过部分(class="left"),class="left"这个div内部又包含一个表示div来表示我们可以拖动的滑块小球。
说一下好处,这样的结构,做出来的样式,在页面检查元素的时候,能够清晰看到每个div和页面上展示的部分是重合的。
如果你的进度条 表示整个长度的div、表示左半部分的div、表示滑块的div不是我这种嵌套结构,而是兄弟节点关系,你就得用样式做相对定位,让后两个兄弟节点上移,这样,检查元素的时候,进度条下面的其他组件的盒子就会浸透到进度条的区域。虽然用户不会检查元素,但是时间久了之后也不方便程序员自己观察,不是吗。
也就是说,我们都希望HTML结构表达的元素和检查元素的时候显示的每个元素的占位是一致的。这也算是对你的HTML结构是否构造合理的一个评价指标。
SEOver="mou
SEOverHandler"
@mousemove="mousemoveHandler" @mouseup="mouseupHandler" :style="pBarStyle">
标记是否按下鼠标
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',percent);
this.isMouseDownOnBall = false;
}
},mou
SEOverHandler(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 + '%';
},}