vue+js拖拽进度条+计数器联动效果(可自定义值,复制代码直接可用)

直接上代码:

       封装slider的组件:

       

<template>
  <div id="container" ref="outContainer">
    <div
      class="innerContainer"
      ref="innerContainer"
      :style="`width:${distance * 100}%`"
    >
      <div
        class="block"
        ref="block"
        :style="`left:${distance * containerWidth - 10}px`"
      ></div>
      <div class="tips" :style="`left:${distance * containerWidth - 68}px`">
         值:{{totalPer}}/{{total}}
      </div>
   
    </div>

    
  </div>
</template>
<script>
export default {
  props: {
    sliderType: {
      type: String,
      default: "",
    },
    initDistance: {
      type: Number,
      default: 0,
    },
    max: {
      type: Number,
      default: 0,
    },
    total:{
      type: Number,
      default: 0,
    }
  },
  data() {
    return {
      initVal: 0,
      distance: 0,
      initX: 0,
      containerWidth: 0,
      isFirst: true,
      totalPer:0
    };
  },
  watch: {
    initDistance(val) {
      //由于我们传递给父组件的值是经过max乘积得到的对应父组件的一个数值,所以要重新将数值转换回来
      this.distance = val / this.max;
    },
  },
  created() {
    console.log(this.total)
  },
  mounted() {
    //获取容器宽度
    this.containerWidth = document.getElementById("container").offsetWidth;
    let block = this.$refs.block;
    //计算出百分比
    let percentage = this.containerWidth / this.max;
    //初始化的默认数值,distance是显示进度条的百分比,initVal是默认移动的距离px
    this.distance = (this.initDistance * percentage) / this.containerWidth;
    this.initVal = this.initDistance * percentage;
    block.onmousedown = (e) => {
      //记录首次点击的位置
      if (this.isFirst) {
        this.initX = e.clientX;
      }
      this.isFirst = false;
      document.onmousemove = (draw) => {
        if (draw.clientX - this.initX + this.initVal < 0) {
          this.distance = 0;
        } else {
          this.distance =
            (draw.clientX - this.initX + this.initVal) / this.containerWidth;
        }
        if (draw.clientX - this.initX + this.initVal >= this.containerWidth) {
          this.distance = 1;
        }
        if(this.sliderType=='sliderVal'){
          this.totalPer =  Math.floor(this.total*this.distance) ==0? 0:Math.floor(this.total*this.distance)
        }else{
          this.totalPer =  (this.total*this.distance).toFixed(2) ==0? 0:(this.total*this.distance).toFixed(2)
        }
        
        this.$emit(`update:${this.sliderType}`, this.distance * this.max);
      };
      document.onmouseup = () => {
        document.onmousedown = document.onmousemove = null;
      };
    };
  },
  computed: {},
  methods: {},
};
</script>
<style lang="less" scoped>
#container {
  width: 400px;
  height: 10px;
  background: #e4e7ed;
  border-radius: 5px;
  margin-top: 20px;
  margin-left: 10px;
  cursor: pointer;
  .innerContainer {
    position: relative;
    height: 100%;
    // width: 0px;
    border-radius: 5px;
    background: #409eff;
    .block {
      position: absolute;
      top: -2px;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      border: 2px solid #409eff;
      background: #ffffff;
      cursor: pointer;
    }
    .tips{
      position: absolute;
      top: 17px;
      color: #ffffff;
      background: black;
      padding: 0 10px;
      min-width: 110px;
      border-radius: 6px;
      text-align: center;
      font-size: 12px;
       z-index: 1;
    }
    .tips:nth-child(1){
      position: absolute;
      top:-50px;
    }
    .tips::after {
        content: "";
        position: absolute;
        bottom: 100%;
        left: 50%;
        margin-left: -5px;
        border-width: 5px;
        border-style: solid;
        border-color: transparent transparent black transparent;
    }
  }
}
</style>

父组件引用:

import slider from "@/components/slider/index.vue";
<div class="top">
        <el-form-item label="最大CPU核数:">
        <div class="slider-inner  ">
          <slider
          v-if="cup_total>0"
            class="mr10"
            :initDistance="initVal"
            :sliderType="'sliderVal'"
            :max="100"
            v-bind:sliderVal.sync="sliderVal"
            :total="cup_total"
          ></slider>
          <el-input-number
            v-model="sliderVal"
            controls-position="right"
            :min="0"
            :max="100"
            @change="handleChange"
          ></el-input-number>
          <span class="span">%</span>
        </div>
      </el-form-item>
      <el-form-item label="最大内存占用(MiB):">
        <div class="slider-inner">
          <slider
          v-if="mem_total>0"
            class="mr10"
            :initDistance="initValue"
            :sliderType="'sliderValue'"
            :max="100"
            v-bind:sliderValue.sync="sliderValue"
            :total="mem_per"
          ></slider>
          <el-input-number
            v-model="sliderValue"
            controls-position="right"
            :min="0"
            :max="100"
            @change="handleChangeValue"
          ></el-input-number>
          <span class="span">%</span>
        </div>
      </el-form-item>
     </div>

data:中定义的值:

watch:

方法:

 

 

效果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值