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 相关文章推荐
Vue3+elementui plus创建项目的方法
Dec 01 Vue.js
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
vue 实现图片懒加载功能
Dec 31 Vue.js
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
vue中三级导航的菜单权限控制
Mar 31 Vue.js
vue基于Teleport实现Modal组件
May 31 Vue.js
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
vue项目多环境配置(.env)的实现
Jul 21 Vue.js
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
一起来看看Vue的核心原理剖析
Mar 24 Vue.js
vue使用watch监听属性变化
Apr 30 Vue.js
vue3不同环境下实现配置代理
May 25 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
php数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
PHP闭包(Closure)使用详解
2013/05/02 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
php实现的日历程序
2015/06/18 PHP
php实现base64图片上传方式实例代码
2017/02/22 PHP
laravel接管Dingo-api和默认的错误处理方式
2019/10/25 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
动态调用CSS文件的JS代码
2010/07/29 Javascript
javascript来定义类的规范小结
2010/11/19 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
js实现简单登录功能的实例代码
2013/11/09 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
在HTML中插入JavaScript代码的示例
2015/06/03 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
基于jPlayer三分屏的制作方法
2016/12/21 Javascript
bootstrap按钮插件(Button)使用方法解析
2017/01/13 Javascript
javascript获取select值的方法完整实例
2019/06/20 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
[38:54]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第一场 11.28
2020/12/01 DOTA
[02:36]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma 选手采访
2021/03/11 DOTA
在Django的视图中使用数据库查询的方法
2015/07/16 Python
python 截取 取出一部分的字符串方法
2017/03/01 Python
python面向对象法实现图书管理系统
2019/04/19 Python
python实现基于朴素贝叶斯的垃圾分类算法
2019/07/09 Python
Python操作Mongodb数据库的方法小结
2019/09/10 Python
Tensorflow获取张量Tensor的具体维数实例
2020/01/19 Python
浅谈TensorFlow中读取图像数据的三种方式
2020/06/30 Python
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
教师自我鉴定范文
2013/11/10 职场文书
30年同学聚会邀请函
2014/01/25 职场文书
汽车销售员如何做职业生涯规划
2014/02/16 职场文书
战友聚会主持词
2014/04/02 职场文书
2016年教师节特级教师获奖感言
2015/12/09 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
分布式Redis Cluster集群搭建与Redis基本用法
2022/02/24 Redis
SQLServer常见数学函数梳理总结
2022/08/05 MySQL