Vue的事件響應(yīng)式進(jìn)度條組件實(shí)例詳解
寫在前面
找了很多vue進(jìn)度條組件,都不包含拖拽和點(diǎn)擊事件,input range倒是原生包含input和change事件,但是直接基于input range做進(jìn)度條的話,樣式部分需要做大量調(diào)整和兼容性處理。即使做好了,將來需要修改外觀,又是一番折騰。
基于以上兩個(gè)原因,做了一個(gè)可以響應(yīng)input和change事件(即一個(gè)是拖動(dòng)進(jìn)度條到某處,一個(gè)是在進(jìn)度條某位置點(diǎn)擊使其值變?yōu)樵撐恢茫┑膁iv實(shí)現(xiàn)的Vue組件,這樣既滿足了對(duì)進(jìn)度條事件的需求,也帶來了如有需求變動(dòng),樣式修改很方便的好處。
效果圖
以上就是可以利用本組件實(shí)現(xiàn)的一些效果,他們都能響應(yīng)input和change兩種事件。
首先是模板部分
認(rèn)真看一下上圖,怎么構(gòu)造HTML模板還是需要一番考慮的,我也是改了好幾次,最后定的這個(gè)結(jié)構(gòu)。首先有一層外包div就不說了。然后外包div下面就一個(gè)class = 'progress'的div,這個(gè)div內(nèi)部的div是表示進(jìn)度條已劃過部分(class="left"),class="left"這個(gè)div內(nèi)部又包含一個(gè)表示div來表示我們可以拖動(dòng)的滑塊小球。
說一下好處,這樣的結(jié)構(gòu),做出來的樣式,在頁面檢查元素的時(shí)候,能夠清晰看到每個(gè)div和頁面上展示的部分是重合的。
如果你的進(jìn)度條 表示整個(gè)長(zhǎng)度的div、表示左半部分的div、表示滑塊的div不是我這種嵌套結(jié)構(gòu),而是兄弟節(jié)點(diǎn)關(guān)系,你就得用樣式做相對(duì)定位,讓后兩個(gè)兄弟節(jié)點(diǎn)上移,這樣,檢查元素的時(shí)候,進(jìn)度條下面的其他組件的盒子就會(huì)浸透到進(jìn)度條的區(qū)域。雖然用戶不會(huì)檢查元素,但是時(shí)間久了之后也不方便程序員自己觀察,不是嗎。
也就是說,我們都希望HTML結(jié)構(gòu)表達(dá)的元素和檢查元素的時(shí)候顯示的每個(gè)元素的占位是一致的。這也算是對(duì)你的HTML結(jié)構(gòu)是否構(gòu)造合理的一個(gè)評(píng)價(jià)指標(biāo)。
<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部分
對(duì)現(xiàn)在就有需求使用這個(gè)帶事件的進(jìn)度條的同學(xué)來說,看看這部分,可以幫助你自己修改、完善它。
而對(duì)于想要先試用該組件的同學(xué),則可以先不看這部分,等你用到發(fā)現(xiàn)該組件功能不足的時(shí)候,再看這部分代碼也不遲。
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', }, // 標(biāo)記是否按下鼠標(biāo) 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){ // 修改進(jìn)度條本身 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){ // 修改進(jìn)度條本身 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){ // 沒有按左鍵進(jìn)入進(jìn)度條 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(){ // 數(shù)據(jù)驗(yàn)證 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:進(jìn)度條已劃過部分背景色
- bgc:進(jìn)度條還未劃過部分背景色
- ballBgc:滑塊背景色
- width:進(jìn)度條占父組件的寬度百分比,傳百分比數(shù)值
- height:進(jìn)度條高度,傳像素值
- max:進(jìn)度條最大值
- min:最小值
- value:當(dāng)前值
事件
- pbar-drag: 拖動(dòng)進(jìn)度條時(shí)觸發(fā),回傳value值和百分比值
- pbar-drag: 點(diǎn)擊進(jìn)度條某一位置時(shí)觸發(fā),回傳value值和百分比值
總結(jié)
以上所述是小編給大家介紹的Vue的事件響應(yīng)式進(jìn)度條組件實(shí)例詳解,希望對(duì)大家有所幫助,如果大家喲任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
vue 路由守衛(wèi)(導(dǎo)航守衛(wèi))及其具體使用
這篇文章主要介紹了vue 路由守衛(wèi)(導(dǎo)航守衛(wèi))及其具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02vue3+echarts實(shí)現(xiàn)好看的圓角環(huán)形圖
這篇文章主要介紹了vue3+echarts實(shí)現(xiàn)好看的圓角環(huán)形圖效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue.js父子組件通信動(dòng)態(tài)綁定的實(shí)例
今天小編就為大家分享一篇vue.js父子組件通信動(dòng)態(tài)綁定的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue-cli項(xiàng)目無法用本機(jī)IP訪問的解決方法
今天小編就為大家分享一篇vue-cli項(xiàng)目無法用本機(jī)IP訪問的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09快速解決vue在ios端下點(diǎn)擊響應(yīng)延時(shí)的問題
今天小編就為大家分享一篇快速解決vue在ios端下點(diǎn)擊響應(yīng)延時(shí)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08詳解Vue+ElementUI從零開始搭建自己的網(wǎng)站(一、環(huán)境搭建)
這篇文章主要介紹了Vue+ElementUI從零開始搭建自己的網(wǎng)站(一、環(huán)境搭建),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04