zoukankan      html  css  js  c++  java
  • vue 的进度条组件

    先看效果:

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

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

    <template>
        <div class="mfc-slider-runway" ref="runway">
            <div class="mfc-slider-bar" :style="{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{
             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;
                 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{
                     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;
       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;
       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%;
       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

     

  • 相关阅读:
    MySQL "show users"
    MySQL
    A MySQL 'create table' syntax example
    MySQL backup
    MySQL show status
    Tomcat, pathinfo, and servlets
    Servlet forward example
    Servlet redirect example
    Java servlet example
    How to forward from one JSP to another JSP
  • 原文地址:https://www.cnblogs.com/muamaker/p/10329004.html
Copyright © 2011-2022 走看看