须要一个可拖动并能设置最大最小值及步长的进度条,所以问了度娘,参考了很多网友写的进度条的代码,终于搞出了这个进度条组件,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"/>