vue 的进度条组件

vue

先看效果:

要想实现如上图的,进度跳效果,有两种方式,首先介绍第一种:

1、自己用 div 写一个,代码如下

<template>

<div class="mfc-slider-runway" ref="runway">

<div class="mfc-slider-bar" :style="{width:w}"></div>

<div class="mfc-slider-button-wrap" :style="{left:w}" ref="thumb">

<div class="mfc-slider-button" ></div>

</div>

</div>

</template>

<script>

//进度条组件

export default{

props:{

min:{ //最小值

type:Number,

default:0

},

max:{ //最大值

type:Number,

default:100

},

step:{ //每步的值为多少

type:Number,

default:1

},

value:{ // v-model 的初始值

type:Number,

default:0

}

},

data(){

return {

startX:0,

moveRun:false,

maxWidth:0,

left:0

};

},

computed:{

w(){

var maxWidth = this.maxWidth ;

if( !maxWidth){

return 0;

}

if(this.min > this.value){

this.value = this.min;

this.$emit("input", this.value);

}

if(this.max < this.value){

this.value = this.max;

this.$emit("input", this.value);

}

var s = ((this.value - this.step - this.min) / (this.max - this.min))*maxWidth; //上限

var e = ((this.value + this.step- this.min ) / (this.max - this.min))*maxWidth; //下限

var left = this.left;

if(left < s || left > e){

//说明value 的值,与 left 容差太大,需要调和,用于外部的 v-model 初始化

console.log("计算容差---");

left = ( (this.value- this.min )/ (this.max - this.min))*maxWidth;

}

return (left / maxWidth)*100 + "%";

}

},

mounted(){

var $thumb = $(this.$refs.thumb);

$thumb.on("mousedown",this.mousedown.bind(this));

$(window).on("mouseup",this.mouseup.bind(this));

this.maxWidth = $(this.$refs.runway).width(); //总共要走的 px 像素

var value = this.value

if(this.min > value){

value = this.min;

}

if(this.max < value){

value = this.max;

}

this.$emit("input", value);

},

methods:{

mousedown(e){

e.preventDefault();

e.stopPropagation();

this.startX = e.clientX ;

this.moveRun = true;

$(window).on("mousemove",this.mousemove.bind(this))

},

mouseup(e){

this.moveRun = false;

$(window).off("mousemove",this.mousemove.bind(this))

},

mousemove(e){

e.preventDefault();

e.stopPropagation();

if(this.moveRun){

var x = e.clientX;

var startX = this.startX;

this.slide(startX,x);

this.startX = x;

}

},

slide(start,end){

var miss = end - start;

if(miss == 0){

return ;

}

var maxWidth = $(this.$refs.runway).width();

if(maxWidth == 0){

return ;

}

var $thumb = $(this.$refs.thumb);

this.offsetLeft = $thumb.offset().left - $thumb.position().left

var left = end - this.offsetLeft;

this.maxWidth = maxWidth;

if(left < 0){

left = 0;

}

if(left > maxWidth){

left = maxWidth;

}

this.left = left;

//----根据 step 的大小,换算出最终的 value 值

var value = (left / maxWidth) * (this.max - this.min) + this.min;

var v = Math.floor(value / this.step);

value = v*this.step + Math.ceil(value - v);

if(this.min > value){

value = this.min;

}

if(this.max < value){

value = this.max;

}

this.$emit("input",value);

}

},

destroyed(){

$(this.$refs.thumb).off("mousedown",this.mousedown.bind(this));

$(window).on("mouseup",this.mouseup.bind(this));

}

}

</script>

<style lang="less">

div.mfc-slider-runway{

width: 100%;

height: 6px;

margin: 10px 0;

background-color: #e4e7ed;

border-radius: 3px;

position: relative;

cursor: pointer;

vertical-align: middle;

div.mfc-slider-bar{

height: 6px;

background-color: #409eff;

border-top-left-radius: 3px;

border-bottom-left-radius: 3px;

position: absolute;

left: 0;

}

div.mfc-slider-button-wrap{

height: 36px;

width: 36px;

text-align: center;

position: absolute;

z-index: 1001;

top: -15px;

transform: translateX(-50%) ;

background-color: transparent;

text-align: center;

user-select: none;

line-height: normal;

div.mfc-slider-button{

width: 16px;

height: 16px;

border: 2px solid #409eff;

background-color: #fff;

border-radius: 50%;

transition: .2s;

user-select: none;

position: absolute;

left: 0;

right: 0;

top:0;

bottom: 0;

margin: auto;

&:hover{

transform: scale(1.2);

cursor: grab;

}

}

}

}

</style>

 

使用:

   import rangeSlide from "./component/range-slide.vue";

<range-slide v-model="test"></range-slide>

<div>

{{test}}

</div>

2、可以使用 input 的新属性  type=range , 然后通过css修改样式

  css:

input[type=range] {

box-sizing: border-box;

-webkit-appearance: none;

-moz-appearance: none;

appearance: none;

width: 100%;

margin: 0;

padding: 0 2px;

/* Add some L/R padding to ensure box shadow of handle is shown */

overflow: hidden;

border: 0;

border-radius: 1px;

outline: none;

background: -webkit-linear-gradient(#649efd, #649efd) no-repeat center;

background: linear-gradient(#649efd, #649efd) no-repeat center;

/* Use a linear gradient to generate only the 2px height background */

background-size: 100% 2px;

pointer-events: none;

vertical-align: middle;

}

input[type=range]:active,

input[type=range]:focus {

outline: none;

}

input[type=range]::-webkit-slider-thumb {

height: 18px;

width: 18px;

border-radius: 18px;

background-color: #fff;

position: relative;

margin: 5px 0;

/* Add some margin to ensure box shadow is shown */

cursor: pointer;

-webkit-appearance: none;

appearance: none;

pointer-events: all;

box-shadow: 0 1px 4px 0.5px rgba(0, 0, 0, 0.25);

}

input[type=range]::-webkit-slider-thumb::before {

content: ' ';

display: block;

position: absolute;

top: 13px;

left: 100%;

width: 2000px;

height: 2px;

}

.multi-range {

position: relative;

height: 32px;

}

.multi-range input[type=range] {

position: absolute;

}

.multi-range input[type=range]:nth-child(1)::-webkit-slider-thumb::before {

background-color: red;

}

.multi-range input[type=range]:nth-child(2) {

background: none;

}

.multi-range input[type=range]:nth-child(2)::-webkit-slider-thumb::before {

background-color: grey;

}

使用:

              <div class="multi-range">

<input type="range">

</div>

 

小结: 因为 input 的 range属性,兼容不是很好,所以,最好还是自己写,但是自己写会遇见很多坑,比如,value值和step的初始化设置,可能会将 value 设置为一个永远也取不到的值,比如 value初始化为 2 , step又为 5

 

以上是 vue 的进度条组件 的全部内容, 来源链接: utcz.com/z/377399.html

回到顶部