Vue實(shí)現(xiàn)圓環(huán)進(jìn)度條的示例
數(shù)據(jù)展示,一直是各行各業(yè)樂(lè)此不疲的需求,具體到前端開(kāi)發(fā)行業(yè),則是各種各種圖表數(shù)據(jù)展示,各種表格數(shù)據(jù)展示,煩不勝煩(繁不勝繁)!
前幾天剛做了折線圖、柱狀圖、餅狀圖之類(lèi)的圖表數(shù)據(jù)展示效果,今天又碰到了類(lèi)似圓環(huán)進(jìn)度條的展示效果。天天跟數(shù)據(jù)打交道,天天跟接口打交道,項(xiàng)目做了不少,菜還是菜,都是淚??!
其實(shí)說(shuō)白了,是自己對(duì)canvas不熟,對(duì)CSS3不熟,所以就找了一個(gè)現(xiàn)成的輪子:
<template> <div class="content" ref="box"> <svg style="transform: rotate(-90deg)" :width="width" :height="width" xmlns="http://www.w3.org/2000/svg"> <circle :r="(width-radius)/2" :cy="width/2" :cx="width/2" :stroke-width="radius" :stroke="backgroundColor" fill="none" /> <circle ref="$bar" :r="(width-radius)/2" :cy="width/2" :cx="width/2" :stroke="barColor" :stroke-width="radius" :stroke-linecap="isRound ? 'round' : 'square'" :stroke-dasharray="(width-radius)*3.14" :stroke-dashoffset="isAnimation ? (width-radius) * 3.14 : (width - radius) * 3.14 * (100 - progress) / 100" fill="none" /> </svg> <div class="center_text" :style="{color, fontSize}"> <p v-if="!$slots.default" class="title">{{progress}}%</p> <slot></slot> </div> </div> </template> <script> export default { props: { radius: { type: [Number, String], default: 20 }, // 進(jìn)度條厚度 progress: { type: [Number, String], default: 20 }, // 進(jìn)度條百分比 barColor: { type: String, default: "#1890ff" }, // 進(jìn)度條顏色 backgroundColor: { type: String, default: "rgba(0,0,0,0.3)" }, // 背景顏色 isAnimation: { // 是否是動(dòng)畫(huà)效果 type: Boolean, default: true }, isRound: { // 是否是圓形畫(huà)筆 type: Boolean, default: true }, id: { // 組件的id,多組件共存時(shí)使用 type: [String, Number], default: 1 }, duration: { // 整個(gè)動(dòng)畫(huà)時(shí)長(zhǎng) type: [String, Number], default: 1000 }, delay: { // 延遲多久執(zhí)行 type: [String, Number], default: 200 }, timeFunction: { // 動(dòng)畫(huà)緩動(dòng)函數(shù) type: String, default: "cubic-bezier(0.99, 0.01, 0.22, 0.94)" }, circleWidth: { //圓環(huán)寬度 type: Number, default: 100, }, color: { //文字顏色 type: String, default: '#000' }, fontSize: { //文字大小 type: String, default: '18px' } }, data() { return { width: this.circleWidth, idStr: `circle_progress_keyframes_${this.id}` }; }, beforeDestroy() { // 清除舊組件的樣式標(biāo)簽 document.getElementById(this.idStr) && document.getElementById(this.idStr).remove(); window.addEventListener(() => {}); }, mounted() { let self = this; this.setCircleWidth(); this.setAnimation(); // 此處不能使用window.onresize window.addEventListener( "resize", debounce(function() { self.setCircleWidth(); self.setAnimation(self); }, 300) ); }, methods: { setCircleWidth() { let box = this.$refs.box; let width = box.clientWidth; let height = box.clientHeight; let cW = width > height ? height : width; this.width = cW; }, setAnimation() { let self = this; if (self.isAnimation) { // 重復(fù)定義判斷 if (document.getElementById(self.idStr)) { console.warn("vue-circle-progress should not have same id style"); document.getElementById(self.idStr).remove(); } // 生成動(dòng)畫(huà)樣式文件 let style = document.createElement("style"); style.id = self.idStr; style.type = "text/css"; style.innerHTML = ` @keyframes circle_progress_keyframes_name_${self.id} { from {stroke-dashoffset: ${(self.width - self.radius) * 3.14}px;} to {stroke-dashoffset: ${((self.width - self.radius) * 3.14 * (100 - self.progress)) / 100}px;}} .circle_progress_bar${ self.id } {animation: circle_progress_keyframes_name_${self.id} ${ self.duration }ms ${self.delay}ms ${self.timeFunction} forwards;}`; // 添加新樣式文件 document.getElementsByTagName("head")[0].appendChild(style); // 往svg元素中添加動(dòng)畫(huà)class self.$refs.$bar.classList.add(`circle_progress_bar${self.id}`); } } } }; </script> <style scoped> .content {height:100%;display:flex;justify-content:center;align-items: center;} .center_text {position:absolute;} </style>
使用方法:
<CircleProgress :id="'circle1'" :circleWidth="40" :radius="7" :progress="30" :isAnimation="true" :backgroundColor="'#E9E9E9'" :barColor="'#FF4F4F'" /> <CircleProgress :id="'circle2'" :circleWidth="40" :radius="7" :progress="50" :isAnimation="true" :backgroundColor="'#E9E9E9'" :barColor="'#FF902A'" /> <CircleProgress :id="'circle3'" :circleWidth="40" :radius="7" :progress="89" :isAnimation="true" :backgroundColor="'#E9E9E9'" :barColor="'#FFDB4F'" /> <CircleProgress :id="'circle4'" :circleWidth="40" :radius="7" :progress="25" :isAnimation="true" :backgroundColor="'#E9E9E9'" :barColor="'#B8D87E'" />
使用時(shí)需要注意一下,如果你的頁(yè)面中同時(shí)使用了超過(guò)兩個(gè)以上的這種圓環(huán)進(jìn)度條,就需要給每個(gè)圓環(huán)進(jìn)度條設(shè)置不同的id,否則,所有圓環(huán)最終展示的數(shù)據(jù)都會(huì)是最后一個(gè)圓環(huán)的數(shù)據(jù)。
代碼中有一個(gè)防抖動(dòng)的函數(shù),這里就貼一下這個(gè)函數(shù):
function debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function () { // 據(jù)上一次觸發(fā)時(shí)間間隔 const last = +new Date() - timestamp // 上次被包裝函數(shù)被調(diào)用時(shí)間間隔last小于設(shè)定時(shí)間間隔wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果設(shè)定為immediate===true,因?yàn)殚_(kāi)始邊界已經(jīng)調(diào)用過(guò)了此處無(wú)需調(diào)用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } }
本文參考的是npm上的一個(gè)圓環(huán)進(jìn)度條的插件vue-circleprogressbar
,之所以沒(méi)有在項(xiàng)目中直接安裝并使用這個(gè)插件,是因?yàn)檫@個(gè)插件有點(diǎn)不太符合我們開(kāi)發(fā)的需求,比如這個(gè)插件不能設(shè)置圓環(huán)的寬度,不能設(shè)置文字的顏色,不能設(shè)置文字的大小,再比如這個(gè)插件僅僅為了防抖而依賴了lodash(這個(gè)lodash的體積還是很大的)。
至于這個(gè)組件在react中的使用,按照react的生命周期,或者react hooks的語(yǔ)法,或者dva模式的語(yǔ)法,稍微改巴改巴就可以使用了,很簡(jiǎn)單,就不再展開(kāi)了。
作者:小壞
以上就是Vue實(shí)現(xiàn)圓環(huán)進(jìn)度條的示例的詳細(xì)內(nèi)容,更多關(guān)于Vue 實(shí)現(xiàn)圓環(huán)進(jìn)度條的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Vue實(shí)現(xiàn)動(dòng)態(tài)圓環(huán)百分比進(jìn)度條
- Springboot項(xiàng)目中運(yùn)用vue+ElementUI+echarts前后端交互實(shí)現(xiàn)動(dòng)態(tài)圓環(huán)圖(推薦)
- Springboot運(yùn)用vue+echarts前后端交互實(shí)現(xiàn)動(dòng)態(tài)圓環(huán)圖
- vue圓環(huán)百分比進(jìn)度條組件功能的實(shí)現(xiàn)
- vue動(dòng)態(tài)繪制四分之三圓環(huán)圖效果
- vue中使用echarts制作圓環(huán)圖的實(shí)例代碼
- vue使用canvas繪制圓環(huán)
相關(guān)文章
VUE : vue-cli中去掉路由中的井號(hào)#操作
這篇文章主要介紹了VUE : vue-cli中去掉路由中的井號(hào)#操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Vue 2.0在IE11中打開(kāi)項(xiàng)目頁(yè)面空白的問(wèn)題解決
這篇文章主要給大家介紹了關(guān)于Vue 2.0在ie 11中打開(kāi)項(xiàng)目頁(yè)面空白問(wèn)題的解決方法,文中詳細(xì)分析出現(xiàn)該問(wèn)題的原因,并給出了詳細(xì)的解決方法,需要的朋友可以參考借鑒,下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-07-07解決vue中無(wú)法動(dòng)態(tài)修改jqgrid組件 url地址的問(wèn)題
下面小編就為大家分享一篇解決vue中無(wú)法動(dòng)態(tài)修改jqgrid組件 url地址的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03