Data display has always been a demand that all walks of life enjoy. Specifically in the front-end development industry, it is a variety of charts and tables that display data, which is extremely annoying (too complicated)! <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 }, // Progress bar thickness progress: { type: [Number, String], default: 20 }, // Progress bar percentage barColor: { type: String, default: "#1890ff" }, // Progress bar color backgroundColor: { type: String, default: "rgba(0,0,0,0.3)" }, // Background color isAnimation: { // Is it an animation effect type: Boolean, default: true }, isRound: { // Is it a circular brush type: Boolean, default: true }, id: { // Component id, used when multiple components coexist type: [String, Number], default: 1 }, duration: { // The entire animation duration type: [String, Number], default: 1000 }, delay: // How long to delay execution type: [String, Number], default: 200 }, timeFunction: { // Animation easing function type: String, default: "cubic-bezier(0.99, 0.01, 0.22, 0.94)" }, circleWidth: { //Ring width type: Number, default: 100, }, color: //Text color type: String, default: '#000' }, fontSize: { //Text size type: String, default: '18px' } }, data() { return { width: this.circleWidth, idStr: `circle_progress_keyframes_${this.id}` }; }, beforeDestroy() { // Clear the style tag of the old component document.getElementById(this.idStr) && document.getElementById(this.idStr).remove(); window.addEventListener(() => {}); }, mounted() { let self = this; this.setCircleWidth(); this.setAnimation(); // window.onresize cannot be used here 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) { // Repeat the definition if (document.getElementById(self.idStr)) { console.warn("vue-circle-progress should not have same id style"); document.getElementById(self.idStr).remove(); } // Generate animation style file 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;}`; // Add a new style file document.getElementsByTagName("head")[0].appendChild(style); // Add animation class to svg element 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> Directions: <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'" /> Please note that if you use more than two such circular progress bars on your page at the same time, you need to set a different ID for each circular progress bar, otherwise, the data finally displayed by all the circles will be the data of the last circle. There is an anti-shake function in the code, here is the function: function debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function () { // According to the last trigger time interval const last = +new Date() - timestamp // The last time the wrapped function was called, the time interval last is less than the set time interval wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // If set to immediate===true, there is no need to call it here because the start boundary has already been called if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } } This article refers to a circular progress bar plugin As for the use of this component in react, it can be used with a slight modification according to the react lifecycle, the syntax of react hooks, or the syntax of dva mode. It is very simple and I will not elaborate on it.
The above is the details of the example of Vue implementing a circular progress bar. For more information about Vue implementing a circular progress bar, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: 4 Ways to Quickly Teach Yourself Linux Commands
>>: Simple Mysql backup BAT script sharing under Windows
1) Introduction to cache mechanism In the Linux s...
Open any web page: for example, http://www.baidu....
At the end of last year, I replaced the opensuse ...
1. Achieve results 2. Data format returned by the...
Installation Environment Description •System vers...
In Linux operations, we often replace and count s...
The concept of lock ①. Lock, in real life, is a t...
Use the following command to create a container a...
Table of contents Business scenario: Effect demon...
This article uses an example to describe the MySQ...
How to solve the timeout problem when pip is used...
1. Introduction to LVM When we manage Linux disks...
Preface Regarding the use of MySQL indexes, we ha...
This article shares the Java connection MySQL und...
Preface When developing a gateway project, the si...