须要一个可拖动并能设置最大最小值及步长的进度条,所以问了度娘,参考了很多网友写的进度条的代码,终于搞出了这个进度条组件,pc 端和挪动端均可用。
代码:
<template>
<div class="progress-bar">
<div class="num">{{num}}</div>
<div class="mask">
<div class="bar"><div class="point"></div></div>
</div>
</div>
</template>
<script>
export default {
name: "progress-bar",
props: {
min: {
// 最小值
type: Number,
default: 0
},
max: {
// 最大值
type: Number,
default: 100
},
step: {
// 每步的值为多少
type: Number,
default: 1
}
},
data() {
return {
num: this.value,
test: ""
};
},
mounted() {let dragSlide = () => {
document.addEventListener(
"touchmove",
function(e) {e.preventDefault();
},
{passive: false}
);
// 勾销挪动端手势长按弹出提示框的操作
document.addEventListener("contextmenu", function(e) {e.preventDefault();
});
this.point = document.querySelector(".point"); // 管制进度条的点
this.pointWidth = parseInt(window.getComputedStyle(this.point, null).width
);
this.bar = document.querySelector(".bar"); // 进度条色彩层
this.mask = document.querySelector(".mask"); // 进度条底层
let lastX = null; // 判断鼠标挪动方向,解决向左侧滑动时候的 bug
let move = e => {let x = e.touches[0].pageX;
let direction = "";
if (lastX == null) {
lastX = x;
return;
}
if (x > lastX) {direction = "right";} else if (x < lastX) {direction = "left";} else {direction = "";}
let mask_left = this.getPosition(this.mask).left;
let point_left = x - mask_left;
if (point_left >= this.mask.offsetWidth - this.pointWidth) {
// 控制点能够滑动的最大值就是进度条的宽度减去控制点的宽度;
point_left = this.mask.offsetWidth - this.pointWidth;
}
if (point_left < 0) {
// 控制点滑动的最小值不能为负
point_left = 0;
}
this.point.style.left = point_left + "px";
this.bar.style.width = point_left + this.pointWidth + "px";
// 计算百分比
let percent =
(point_left / (this.mask.offsetWidth - this.pointWidth)) * 100;
if (percent < 0.5 && direction == "right") {percent = Math.ceil(percent);
} else if (percent > 0.5 && direction == "right") {percent = Math.floor(percent);
} else {percent = Math.ceil(percent);
}
let value = (percent / 100) * (this.max - this.min) + this.min;
let v = Math.floor(value / this.step);
value = v * this.step;
this.num = value;
};
this.point.addEventListener("touchmove", move);
};
let drag0 = new dragSlide();},
methods: {getPosition(node) {
// 获取元素的相对地位, 工具函数
let left = node.offsetLeft; // 获取元素绝对于其父元素的 left 值 var left
let top = node.offsetTop;
let current = node.offsetParent; // 获得元素的 offsetParent // 始终循环直到根元素
while (current != null) {
left += current.offsetLeft;
top += current.offsetTop;
current = current.offsetParent;
}
return {
left: left,
top: top
};
}
}
};
</script>
<style lang="scss">
* {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.progress-bar {
text-align: left;
.mask {
width: 320px;
height: 20px;
background-color: #dddddd;
border-radius: 10px;
position: absolute;
}
.bar {
height: 20px;
background-color: #1069db;
position: absolute;
z-index: 2;
border-radius: 10px;
bottom: 0;
left: 0;
}
.point {
width: 24px;
height: 24px;
border-radius: 50%;
border: 1px solid #1069db;
position: absolute;
bottom: -3px;
left: 0;
z-index: 3;
background-color: white;
}
.num {
text-align: center;
padding-bottom: 20px;
}
}
</style>
组件应用办法:
// 例如:
<progress-bar :max="200000" :min="10000" :step="10000"/>