<template> <div class="slider" ref="slider"> <div class="process" :style="{width}"></div> <div class="thunk" ref="trunk" :style="{left}"> <div class="block"></div> <!-- <div class="tips"> <span>{{scale*100}}</span> <i class="fas fa-caret-down"></i> </div> --> </div> <!-- <div class="opacity" style="left:-21px;top:-5px;">0%</div> --> <div class="opacity" style=" color:#83C8FE; right:-50px;top:-5px;">{{parseInt(scale*100)}}%</div> </div> </template> <script> /* * min 进度条最小值 * max 进度条最大值 * v-model 对当前值进行双向绑定实时显示拖拽进度 * */ export default { props: { min: { type: Number, default: 0 }, max: { type: Number, default: 100 }, value: { type: String, default: '100' }, list:{ type:Object, default: { } } }, data() { return { slider: null, //滚动条DOM元素 thunk: null, //拖拽DOM元素 per: this.value //当前值 }; }, //渲染到页面的时候 mounted() { this.slider = this.$refs.slider; this.thunk = this.$refs.trunk; var _this = this; this.thunk.onmousedown = function(e) { var width = parseInt(_this.width); var disX = e.clientX; document.onmousemove = function(e) { // value, left, width // 当value变化的时候,会通过计算属性修改left,width // 拖拽的时候获取的新width var newWidth = e.clientX - disX + width; // 拖拽的时候得到新的百分比 var scale = newWidth / _this.slider.offsetWidth; _this.per = Math.ceil((_this.max - _this.min) * scale + _this.min); _this.per = Math.max(_this.per, _this.min); _this.per = Math.min(_this.per, _this.max); }; document.onmouseup = function() { document.onmousemove = document.onmouseup = null; }; return false; }; }, computed: { // 设置一个百分比,提供计算slider进度宽度和trunk的left值 // 对应公式为 当前值-最小值/最大值-最小值 = slider进度width / slider总width // trunk left = slider进度width + trunk宽度/2 scale() { return (this.per - this.min) / (this.max - this.min); }, width() { if (this.slider) { return this.slider.offsetWidth * this.scale + "px"; } else { return 0 + "px"; } }, left() { if (this.slider) { return ( this.slider.offsetWidth * this.scale - this.thunk.offsetWidth / 2 + "px" ); } else { return 0 + "px"; } } }, watch: { scale(val, oldVal) { // console.log('per',val, oldVal) this.$emit("SetOpacityConfig",this.list,val); } } }; </script> <style> .clear:after { content: ""; display: block; clear: both; } .slider { position: relative; margin: 10px 0px 5px 25px; width: 310px; height: 7px; background:rgba(255, 255, 255,0); border: 1px solid #83C8FE; border-radius: 5px; cursor: pointer; } .slider .opacity { position: absolute; font-size: 20px; font-family: Agency FB; color: rgb(255, 255, 255); font-weight: bold; line-height: 15px; } .slider .process { position: absolute; left: 0; top: 0; width: 112px; height: 5px; border-radius: 5px; background: #83C8FE; } .slider .thunk { position: absolute; left: 100px; top: -4px; width: 20px; height: 20px; } .slider .block { margin-top:-3px; margin-left:3px; width: 8px; height: 20px; border-radius: 5px; border: 1px solid #83C8FE; background: #83C8FE; transition: 0.2s all; } .slider .tips { position: absolute; left: -2px; bottom: 24px; min-width: 10px; text-align: center; padding: 0px 1px 0px 1px; background: #83C8FE; border-radius: 2px; height: 16px; line-height: 16px; color: #fff; font-weight: bold; font-size: 14px; } .slider .tips i { position: absolute; margin-left: -5px; left: 50%; bottom: -9px; font-size: 14px; color: #83C8FE; } .slider .block:hover { transform: scale(1.1); opacity: 0.9; } </style>