首頁  >  文章  >  web前端  >  在Vue中如何實作事件響應式進度條元件

在Vue中如何實作事件響應式進度條元件

亚连
亚连原創
2018-06-07 17:31:593512瀏覽

這篇文章主要介紹了Vue的事件響應式進度條元件的實例程式碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

寫在前面

找了很多vue進度條元件,都不包含拖曳和點擊事件,input range倒是原生包含input和change事件,但是直接基於input range做進度條的話,樣式部分需要做大量調整和相容性處理。即使做好了,將來需要修改外觀,又是一番折騰。

基於以上兩個原因,做了一個可以回應input和change事件(即一個是拖曳進度​​條到某處,一個是在進度條某處點擊使其值變為該位置)的p實現的Vue元件,這樣既滿足了進度條事件的需求,也帶來瞭如有需求變動,樣式修改很方便的好處。

效果圖

以上就是可以利用本元件實現的一些效果,他們都能回應input和change兩種事件。

首先是模板部分

認真看上圖,怎麼構造HTML模板還是需要一番考慮的,我也是改了好幾次,最後定的這個結構。首先有一層外包p就不說了。然後外包p下面就一個class = 'progress'的p,這個p內部的p是表示進度條已劃過部分(class="left"),class="left"這個p內部又包含一個表示p來表示我們可以拖曳的滑塊小球。

說一下好處,這樣的結構,做出來的樣式,在頁面檢查元素的時候,能夠清楚地看到每個p和頁面上展示的部分是重合的。

如果你的進度條表示整個長度的p、表示左半部的p、表示滑塊的p不是我這種嵌套結構,而是兄弟節點關係,你就得用樣式做相對定位,讓後兩個兄弟節點上移,這樣,檢查元素的時候,進度條下面的其他組件的盒子就會浸透到進度條的區域。雖然使用者不會檢查元素,但是時間久了之後也不方便程式設計師自己觀察,不是嗎。

也就是說,我們都希望HTML結構表達的元素和檢查元素的時候顯示的每個元素的佔位是一致的。這也算是對你的HTML結構是否構造合理的一個評估指標。

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

js部分

對現在就有需求使用這個帶事件的進度條的同學來說,看看這部分,可以幫助你自己修改、完善它。

而對於想要先試用該元件的同學,則可以先不看這部分,等你用到發現該元件功能不足的時候,再看這部分程式碼也不遲。

export default {
  name: &#39;ProgressBar&#39;,
  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: {
     &#39;width&#39;: this.width,
    },
    pBarStyle: {
     &#39;backgroundColor&#39;: this.bgc,
     &#39;height&#39;: this.height,
    },
    leftStyle: {
     &#39;width&#39;: this.progressPercent + &#39;%&#39;,
     &#39;background&#39;: this.leftBg,
     &#39;height&#39;: this.height,
    },
    ballStyle: {
     &#39;backgroundColor&#39;: this.ballBgc,
     &#39;height&#39;: this.height,
     &#39;width&#39;: this.height,
     &#39;borderRadius&#39;: parseInt(this.height) / 2 + &#39;px&#39;,
     &#39;right&#39;: - parseInt(this.height) / 2 + &#39;px&#39;,
    },
    // 标记是否按下鼠标
    isMouseDownOnBall: false,
   }
  },
  computed: {
   progressPercent(){
    return (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100;
   },
   progressElement(){
    return this.$el.getElementsByClassName(&#39;progress&#39;)[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 + &#39;%&#39;;
     // 修改value
     this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
     this.$emit(&#39;pbar-drag&#39;, 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 + &#39;%&#39;;
     // 修改value
     this.pValue = this.pMin + decimal * (this.pMax - this.pMin);
     this.$emit(&#39;pbar-seek&#39;, 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 + &#39;%&#39;;
   }
  },
  mounted(){
   // 数据验证
   if(this.max < this.min){
    console.error("max can&#39;t less than min !");
   }
   // 初始百分比
   this.leftStyle.width = (this.pValue - this.pMin) / (this.pMax - this.pMin) * 100 + &#39;%&#39;;
  },
 }

安裝、使用

位址

程式碼庫位址在GitHub

安裝、使用

npm install vue-draggable-progressbar --save
import progressBar from &#39;vue-draggable-progressbar&#39;

使用案例:

<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值和百分比值

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

在jQuery中有關Dom元素使用方法?

在js中常用陣列函數有哪些?

關於vue2.0中datepicker使用方法#

以上是在Vue中如何實作事件響應式進度條元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn