vue实现拖拽进度条


Posted in Vue.js onMarch 01, 2021

本文实例为大家分享了vue实现拖拽进度条的具体代码,供大家参考,具体内容如下

vue实现拖拽进度条

组件代码:

<template>
 <div>
  <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>
  <div>
   <button
    @click="
     () => {
      this.per++;
     }
    "
   >
    +</button
   >{{ per }}%<button
    @click="
     () => {
      if (this.per > 0) {
       this.per--;
      }
     }
    "
   >
    -
   </button>
  </div>
 </div>
</template>
<script>
/*
 * min 进度条最小值
 * max 进度条最大值
 * v-model 对当前值进行双向绑定实时显示拖拽进度
 * */
export default {
 props: ["min", "max", "value"],
 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);
    _this.$emit("input", _this.per);
   };
   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";
   }
  },
 },
};
</script>
<style>
.box {
 margin: 100px auto 0;
 width: 80%;
}
.clear:after {
 content: "";
 display: block;
 clear: both;
}
.slider {
 user-select: none;
 position: relative;
 margin: 20px 0;
 width: 400px;
 height: 10px;
 background: #e4e7ed;
 border-radius: 5px;
 cursor: pointer;
}
.slider .process {
 position: absolute;
 left: 0;
 top: 0;
 width: 112px;
 height: 10px;
 border-radius: 5px;
 background: #81b159;
}
.slider .thunk {
 position: absolute;
 left: 100px;
 top: -7px;
 width: 20px;
 height: 20px;
}
.slider .block {
 width: 20px;
 height: 20px;
 border-radius: 50%;
 border: 2px solid #409eff;
 background: rgba(255, 255, 255, 1);
 transition: 0.2s all;
}
.slider .tips {
 position: absolute;
 left: -7px;
 bottom: 30px;
 min-width: 15px;
 text-align: center;
 padding: 4px 8px;
 /* background: #000; */
 border-radius: 5px;
 height: 24px;
 color: #fff;
}
.slider .tips i {
 position: absolute;
 margin-left: -5px;
 left: 50%;
 bottom: -9px;
 font-size: 16px;
 color: #000;
}
.slider .block:hover {
 transform: scale(1.1);
 opacity: 0.6;
}
</style>

调用:

<template>
 <slider :min="0" :max="100" v-model="per"></slider>
</template>

<script>
import slider from "@/components/slider";
export default {
 data() {
  return {};
 },
 computed: {
  per: {
   get() {
    return 0;
   },
   set(val) {
    console.log(val);
   },
  },
 },
 components: { slider },
 mounted() {},
 methods: {},
};
</script>

<style >
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
解决vue elementUI 使用el-select 时 change事件的触发问题
Nov 17 Vue.js
vue3.0实现点击切换验证码(组件)及校验
Nov 18 Vue.js
Vue3配置axios跨域实现过程解析
Nov 25 Vue.js
ESLint 是如何检查 .vue 文件的
Nov 30 Vue.js
Vue如何实现验证码输入交互
Dec 07 Vue.js
vue下拉刷新组件的开发及slot的使用详解
Dec 23 Vue.js
vuex的使用步骤
Jan 06 Vue.js
vue keep-alive的简单总结
Jan 25 Vue.js
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 Vue.js
Vue-router编程式导航的两种实现代码
Mar 04 Vue.js
vue3如何优雅的实现移动端登录注册模块
Mar 29 Vue.js
浅谈Vue的computed计算属性
Mar 21 Vue.js
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
Mar 01 #Vue.js
vue前端和Django后端如何查询一定时间段内的数据
Feb 28 #Vue.js
vue-router路由懒加载及实现的3种方式
Feb 28 #Vue.js
vue-router懒加载的3种方式汇总
Feb 28 #Vue.js
Vue SPA 首屏优化方案
Feb 26 #Vue.js
vue 动态添加的路由页面刷新时失效的原因及解决方案
Feb 26 #Vue.js
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
Feb 26 #Vue.js
You might like
德劲1107的电路分析与打磨
2021/03/02 无线电
谈PHP生成静态页面分析 模板+缓存+写文件
2009/08/17 PHP
ECSHOP在PHP5.5及高版本上报错的解决方法
2015/08/31 PHP
理解PHP中的Session及对Session有效期的控制
2016/01/08 PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
2016/06/13 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
PHP Ajax跨域问题解决方案代码实例
2020/08/01 PHP
javascript使用location.search的示例
2013/11/05 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
jQuery实现contains方法不区分大小写的方法
2015/02/13 Javascript
JS实现兼容性好,自动置顶的淘宝悬浮工具栏效果
2015/09/18 Javascript
PhotoSwipe异步动态加载图片方法
2016/08/25 Javascript
JS+CSS3制作炫酷的弹窗效果
2016/11/08 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
2017/12/19 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
深入解析vue 源码目录及构建过程分析
2019/04/24 Javascript
Vue中通过属性绑定为元素绑定style行内样式的实例代码
2020/04/30 Javascript
关于uniApp editor微信滑动问题
2021/01/15 Javascript
python批量提取word内信息
2015/08/09 Python
python的paramiko模块实现远程控制和传输示例
2017/10/13 Python
Python Cookie 读取和保存方法
2018/12/28 Python
Python.append()与Python.expand()用法详解
2019/12/18 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)
2020/02/20 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
MYSQL支持事务吗
2013/08/09 面试题
《问银河》教学反思
2014/02/19 职场文书
中文教师求职信
2014/02/22 职场文书
《水上飞机》教学反思
2014/04/10 职场文书
计算机专业自荐信
2015/03/05 职场文书
大学生自我推荐信范文
2015/03/24 职场文书
教师思想工作总结2015
2015/05/13 职场文书
2015领导干部廉洁自律工作总结
2015/07/23 职场文书
2016高一新生军训心得体会
2016/01/11 职场文书
前端使用svg图片改色实现示例
2022/07/23 HTML / CSS