Vue的事件响应式进度条组件实例详解

写在前面

找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理。即使做好了,将来需要修改外观,又是一番折腾。

基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处。

效果图

以上就是可以利用本组件实现的一些效果,他们都能响应input和change两种事件。

首先是模板部分

认真看一下上图,怎么构造HTML模板还是需要一番考虑的,我也是改了好几次,最后定的这个结构。首先有一层外包div就不说了。然后外包div下面就一个class = 'progress'的div,这个div内部的div是表示进度条已划过部分(class="left"),class="left"这个div内部又包含一个表示div来表示我们可以拖动的滑块小球。

说一下好处,这样的结构,做出来的样式,在页面检查元素的时候,能够清晰看到每个div和页面上展示的部分是重合的。

如果你的进度条 表示整个长度的div、表示左半部分的div、表示滑块的div不是我这种嵌套结构,而是兄弟节点关系,你就得用样式做相对定位,让后两个兄弟节点上移,这样,检查元素的时候,进度条下面的其他组件的盒子就会浸透到进度条的区域。虽然用户不会检查元素,但是时间久了之后也不方便程序员自己观察,不是吗。

也就是说,我们都希望HTML结构表达的元素和检查元素的时候显示的每个元素的占位是一致的。这也算是对你的HTML结构是否构造合理的一个评价指标。

<template>
  <div class="progress-wrapper" :style="wrapStyle">
    <div class="progress" @mousedown="mousedownHandler" @mouseover="mouseoverHandler"
       @mousemove="mousemoveHandler" @mouseup="mouseupHandler" :style="pBarStyle">
      <div class="left" :style="leftStyle">
        <div class="ball" :style="ballStyle"></div>
      </div>
      <slot></slot>
    </div>
  </div>
</template>

js部分

对现在就有需求使用这个带事件的进度条的同学来说,看看这部分,可以帮助你自己修改、完善它。

而对于想要先试用该组件的同学,则可以先不看这部分,等你用到发现该组件功能不足的时候,再看这部分代码也不迟。

export default {
    name: 'ProgressBar',
    props: {
      leftBg: String,
      bgc: String,
      ballBgc: String,
      height: String,
      width: String,
      max: {
        type: Number,
        default: 100,
      },
      min: {
        type: Number,
        default: 0,
      },
      value: {
        type: Number,
        default: 36,
      },
    },
    data: function () {
      return {
        pValue: this.value,
        pMax: this.max,
        pMin: this.min,
        wrapStyle: {
          'width': this.width,
        },
        pBarStyle: {
          'backgroundColor': this.bgc,
          'height': this.height,
        },
        leftStyle: {
          'width': this.progressPercent + '%',
          'background': this.leftBg,
          'height': this.height,
        },
        ballStyle: {
          'backgroundColor': this.ballBgc,
          'height': this.height,
          'width': this.height,
          'borderRadius': parseInt(this.height) / 2 + 'px',
          'right': - parseInt(this.height) / 2 + 'px',
        },
        // 标记是否按下鼠标
        isMouseDownOnBall: false,
      }
    },
    computed: {
      progressPercent(){
        return (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100;
      },
      progressElement(){
        return this.$el.getElementsByClassName('progress')[0];
      },
    },
    methods: {
      mousedownHandler(e){
        if(e.which === 1){
          this.isMouseDownOnBall = true;
        }
      },
      mousemoveHandler(e){
        if(this.isMouseDownOnBall === true){
          // 修改进度条本身
          let decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
          let percent = decimal * 100;
          this.leftStyle.width = percent + '%';
          // 修改value
          this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
          this.$emit('pbar-drag', this.pValue, percent);
        }
      },
      mouseupHandler(e){
        if(this.isMouseDownOnBall){
          // 修改进度条本身
          let decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
          let percent = decimal * 100;
          this.leftStyle.width = percent + '%';
          // 修改value
          this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
          this.$emit('pbar-seek', this.pValue, percent);
          this.isMouseDownOnBall = false;
        }
      },
      mouseoverHandler(e){
        // 没有按左键进入进度条
        if(e.which === 0){
          this.isMouseDownOnBall = false;
        }
      }
    },
    watch: {
      max(cur, old){
        this.pMax = cur;
      },
      min(cur, old){
        this.pMin = cur;
      },
      value(cur, old){
        this.pValue = cur;
      },
      progressPercent(cur, old){
        this.leftStyle.width = cur + '%';
      }
    },
    mounted(){
      // 数据验证
      if(this.max < this.min){
        console.error("max can't less than min !");
      }
      // 初始百分比
      this.leftStyle.width = (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100 + '%';
    },
  }

安装、使用

地址

代码库地址在GitHub

安装、使用

npm install vue-draggable-progressbar --save
import progressBar from 'vue-draggable-progressbar'

用例:

<progress-bar ref="aa"></progress-bar>
<progress-bar width="40%" leftBg="greenyellow" bgc="#ccc" ballBgc="red"></progress-bar>
<progress-bar width="60%" leftBg="linear-gradient(to right, yellow, pink)" bgc="#ccc" ballBgc="red"></progress-bar>
<progress-bar width="80%" leftBg="yellow" bgc="#ccc" ballBgc="red" height="30px"></progress-bar>
<progress-bar leftBg="greenyellow" bgc="#ccc" ballBgc="rgba(255,0,0,0.2)" height="40px"></progress-bar>
<progress-bar leftBg="greenyellow" bgc="#ccc" ballBgc="red" :max="max" :value="value" :min="min"
       @pbar-drag="drag" @pbar-seek="seek"></progress-bar>

组件props

  • leftBg:进度条已划过部分背景色
  • bgc:进度条还未划过部分背景色
  • ballBgc:滑块背景色
  • width:进度条占父组件的宽度百分比,传百分比数值
  • height:进度条高度,传像素值
  • max:进度条最大值
  • min:最小值
  • value:当前值

事件

  • pbar-drag: 拖动进度条时触发,回传value值和百分比值
  • pbar-drag: 点击进度条某一位置时触发,回传value值和百分比值

总结

以上所述是小编给大家介绍的Vue的事件响应式进度条组件实例详解,希望对大家有所帮助,如果大家哟任何疑问欢迎给我留言,小编会及时回复大家的!

您可能感兴趣的文章:

  • 在vue项目中使用Nprogress.js进度条的方法
(0)

相关推荐

  • 在vue项目中使用Nprogress.js进度条的方法

    NProgress.js提供页面加载进度条效果,当页面打开加载时,在页面顶部会出现进度条加载动画.NProgress.js是轻量级的进度条组件,使用简便,可以很方便集成到单页面应用中. Ajaxyy应用程序的细长进度条.灵感来自Google,YouTube和Medium. 在vue中使用nprogress.js 安装 $ bower install --save nprogress $ npm install --save nprogress 在项目中引入 在main.js中引入要使用的npro

  • Vue的事件响应式进度条组件实例详解

    写在前面 找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理.即使做好了,将来需要修改外观,又是一番折腾. 基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处. 效果图 以

  • Bootstrap进度条组件知识详解

    在网页中,经常见到进度条效果,如:平分系统.加载状态等,进度条组件使用了css3的transition和animation属性来完成一些特效,这些特效在IE9及IE9以下版本.Firefox的老版本中并不支持,Opera 12 不支持 animation 属性. 进度条和其他独立组件一样,开发者可以根据自己的需要选择对应的版本: LESS: progress-bars.less SASS: _progress-bars.scss 基础进度条 实现原理: 需要两个容器,外容器使用类名.progre

  • Vue.js3.2响应式部分的优化升级详解

    目录 背景 响应式实现原理 依赖收集 派发通知 副作用函数 响应式实现的优化 依赖收集的优化 响应式 API 的优化 trackOpBit 的设计 总结 背景 Vue 3 正式发布距今已经快一年了,相信很多小伙伴已经在生产环境用上了 Vue 3 了.如今,Vue.js 3.2 已经正式发布,而这次 minor 版本的升级主要体现在源码层级的优化,对于用户的使用层面来说其实变化并不大.其中一个吸引我的点是提升了响应式的性能: More efficient ref implementation (~

  • 基于 D3.js 绘制动态进度条的实例详解

    D3 是什么 D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档.听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可视化的.如果你不知道什么是 JavaScript ,请先学习一下 JavaScript,推荐阮一峰老师的教程. JavaScript 文件的后缀名通常为 .js,故 D3 也常使用 D3.js 称呼.D3 提供了各种简单易用的函数,大大简化了 JavaScript 操作数据的难度.由于

  • bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)

    本文实例为大家分享了bootstrap响应式导航条模板展示的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name=&quo

  • vue 页面加载进度条组件实例

    页面加载进度条最初我是在youtube上看到的,后面几乎在各大网站上都能见到它的身影,可以让用户在加载页面的时候不会对着完全空白的页面发呆,提升用户体验 但是从开发角度讲,这种进度条在真实性上确实很难把握,因为在逻辑代码加载完成之前,我们都不能统计到进度,而逻辑代码自身的进度也无法统计.另外,我们不可能监控到所有资源的加载情况. 事实上,用户并不是在乎你的页面究竟加载了百分之几,而真正关心的是离加载完还有多久,以及这个空白页面是没有加载完,还是加载完就是空白的.所以没我们需要去"模拟"

  • vue组件编写之todolist组件实例详解

    我们在topNav这个页面上插入一个todolist子组件 我不知道怎么回事,这里的markdown的代码总是串行..所以代码看得不舒服,见谅啊,我最后会放github的源代码地址. 1. 父组件topNav中注册子组件,引入子组件 <template> <div> <p>下面这一行就是定义的组件名称</p> <todo-list></todo-list> <router-view></router-view>

  • 基于vue+canvas的excel-like组件实例详解

    a vue component,基于vue的表格组件,主要解决大数据量的表格渲染性能问题,使用canvas绘制表格,同时支持类似excel的批量选中,复制黏贴删除,实时编辑等功能. vue-grid-canvas Install NPM / Yarn Install the package: npm install vue-canvas-grid --save Then import it in your project import Vue from 'vue' import Grid fro

  • vue实现简单表格组件实例详解

    本来想这一周做一个关于vuex的总结的,但是由于朋友反应说还不知道如何用vue去写一个组件,所以在此写写一篇文章来说明下如何去写vue页面或者组件.vue的核心思想就是组件,什么是组件呢?按照我的理解组件就是装配页面的零件,比如一辆车有大大小小许多零件组成,那么同样的一个页面,也是有许多组件构成的比如说头部组件 按钮组件等等,vue三大核心组件 路由 状态管理,路由控制页面的渲染,页面由组件组成,数据有vuex进行管理和改变.下面我会以一个简单的案例来说 第一步:构建一个简单的vue项目,老规矩

  • 基于layui框架响应式布局的一些使用详解

    写在前面的 因为公司的需要,这几天学习了layui框架,稍微有一些心得.介绍就不多说,贴上官网的说明文档,目前是2.0版本,上面有很详细的介绍. 官网地址:https://www.layui.com/doc/element/layout.html 简单的布局 layui的响应式使用十分简单,虽然官网写了很多很详细,但某种意义上增加了新手学习的难度和劝退的可能.但其实总结下来如何使用响应式布局就几个步骤: 第一,在第一个div设置一个布局类 ,通常我只使用两个类,分别是:layui-contain

随机推荐