Writing in the front

I found a lot of vue progress bar components, none of which contain drag and click events. The Input range does contain input and change events, but if you build the progress bar directly from the Input range, you need to do a lot of adjustment and compatibility. Even if you do, you will need to modify the appearance in the future.

Based on the above two reasons, made a can respond to the input and change event (i.e. a drag the progress bar is in somewhere, one is a location in the progress bar click on turn its value into the location) Vue div implementation of components, this will not only satisfy the demand for the progress bar events, also brought if there are any changes in demand, the benefits of style changes very convenient.

The application scenario of the event-responsive progress bar is to customize the progress bar of the video player.

rendering

These are some of the effects you can achieve with this component, and they all respond to both input and change events.

The first is the template section

If you take a look at the image above, you need to think about how to construct the HTML template. I changed it several times and finally settled on this structure. First, there is a layer of outsourcing div. The div inside the div represents the part of the progress bar that has been moved (class=”left”), and the div inside the div represents the slider ball that we can drag.

The advantage of this is that the structure, the styling, when you look at the elements on the page, you can clearly see that each div overlaps with what’s displayed on the page.

If your progress bar div for the full length, div for the left, div for the slider are not nested like I am, but are siblings, you can style them so that the next two siblings move up to the first sibling element, so that when you check the element, The boxes of other components below the progress bar will saturate the area of the progress bar. Although the user does not check the elements, it is not convenient for the programmer to observe them over time, is it not?

That is, we all want the elements represented in the HTML structure to have the same placeholders for each element that is displayed when the element is examined. This is also an indicator of how well your HTML is structured.

<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>
Copy the code

Js part

For those of you who need to use the progress bar with events right now, check out this section to help you modify and improve it yourself.

For those of you who want to try this component out first, you can skip this section and look at this part of the code again when you find that the component is not functional enough.

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 + The '%'.'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'}, // mark whether to press 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){// Modify the progress bar itselflet decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
                    let percent = decimal * 100;
                    this.leftStyle.width = percent + The '%'; // Change value this.pvalue = this.pmin + decimal * (this.pMax - this.pMin);
                    this.$emit('pbar-drag', this.pValue, percent);
                }
            },
            mouseupHandler(e){
                if(this.ismousedownonball){// Modify the progress bar itselflet decimal = (e.clientX - this.$el.offsetLeft) / this.progressElement.clientWidth;
                    let percent = decimal * 100;
                    this.leftStyle.width = percent + The '%'; // Change value this.pvalue = this.pmin + decimal * (this.pMax - this.pMin);
                    this.$emit('pbar-seek', this.pValue, percent);

                    this.isMouseDownOnBall = false; }}, mouseoverHandler(e){// The progress bar is not left pressedif(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 + The '%'; }},mounted(){// Data validationif(this.max < this.min){
                console.error("max can't less than min !"); } // The initial percentage this.leftstyle.width = (this.pvalue - this.pmin) / (this.pMax - this.pMin) * 100 + The '%'; }},Copy the code

Installation and use

address

The code base address is on GitHub

Installation and use

npm install vue-draggable-progressbar --save

import progressBar from 'vue-draggable-progressbar'
Copy the code

Use cases:

<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>

Copy the code

Component props

  • LeftBg: Progress bar has delimited part of the background color
  • BGC: The progress bar has not crossed some background colors
  • BallBgc: Slider background color
  • Width: indicates the percentage of the width of the progress bar to the parent component
  • Height: Indicates the height of the progress bar
  • Max: indicates the maximum number of progress bars
  • Min: indicates the minimum value
  • Value: indicates the current value

The event

  • Pbar-drag: Triggered when dragging the progress bar, returns value and percentage values
  • Pbar-drag: Triggered when clicking on a position in the progress bar, returns value and percentage values

The last

If this article helped you, please give it a thumbs up. Practice is the key to programming, so take action!

About the author

Author: Cloud shortage cup tilt

Technology blog | | making | | Denver home page