1.详情介绍

在日常的开发当中,随着项目的需求复杂化,自定义组件也越来越常见,而且扩展性也比一些组件库要更加全面,比如视频播放器的进度条。

可自定义设置以下属性:
当前进度value,默认50
是否可拖拽isDrag,默认true
设置最小值min,默认0
设置最大值max,默认100
进度条颜色bgColor,默认#4ab157

效果如下图:

2.编码介绍

template部分

<template><div class="slider" ref="slider" @click.stop="handelClickSlider"><div class="process" :style="{ width,background:bgColor }"></div><div class="thunk" ref="trunk" :style="{ left }"><div class="block" ref="dot"></div></div></div></template>

js部分

<script>/* * min 进度条最小值 * max 进度条最大值 * v-model 对当前值进行双向绑定实时显示拖拽进度 * */export default {props: {// 最小值min: {type: Number,default: 0,},// 最大值max: {type: Number,default: 100,},// 当前值value: {type: Number,default: 0,},// 进度条颜色bgColor: {type: String,default: "#4ab157",},// 是否可拖拽isDrag: {type: Boolean,default: true,},},data() {return {slider: null, //滚动条DOM元素thunk: null, //拖拽DOM元素per: this.value, //当前值};},mounted() {this.slider = this.$refs.slider;this.thunk = this.$refs.trunk;var _this = this;if (!this.isDrag) return;this.thunk.onmousedown = function (e) {var width = parseInt(_this.width);var disX = e.clientX;document.onmousemove = function (e) {// value, left, width// 当value变化的时候,会通过计算属性修改left,width// 拖拽的时候获取的新widthvar newWidth = e.clientX - disX + width;// 计算百分比var scale = newWidth / _this.slider.offsetWidth;_this.per = Math.ceil((_this.max - _this.min) * scale + _this.min); //取整// 限制值大小_this.per = Math.max(_this.per, _this.min);_this.per = Math.min(_this.per, _this.max);_this.$emit("input", _this.per);};document.onmouseup = function () {//当拖拽停止发送事件_this.$emit("stop", _this.per);//清除拖拽事件document.onmousemove = document.onmouseup = null;};};},methods: {handelClickSlider(event) {//禁止点击if (!this.isDrag) return;const dot = this.$refs.dot;if (event.target == dot) return;//获取元素的宽度llet width = this.slider.offsetWidth;//获取元素的左边距let ev = event || window.event;//获取当前点击位置的百分比let scale = ((ev.offsetX / width) * 100).toFixed(2);this.per = scale;},},computed: {// 设置一个百分比,提供计算slider进度宽度和trunk的left值// 对应公式为当前值-最小值/最大值-最小值 = slider进度width / slider总width// trunk left =slider进度width + trunk宽度/2scale() {return (this.per - this.min) / (this.max - this.min);},width() {return this.slider " />this.slider.offsetWidth * this.scale + "px" : "0px";},left() {return this.slider ? this.slider.offsetWidth * this.scale - this.thunk.offsetWidth / 2 +"px" : "0px";},},watch: {value: {handler: function () {this.per = this.value;},},},};</script>

css部分

<style scoped>.box {margin: 100px auto 0;width: 80%;}.clear:after {content: "";display: block;clear: both;}.slider {position: relative;margin: 20px 0;width: 100%;height: 10px;top: 50%;background: #747475;border-radius: 5px;cursor: pointer;z-index: 99999;}.slider .process {position: absolute;left: 0;top: 0;width: 112px;height: 10px;border-radius: 5px;background: #4ab157;z-index: 111;}.slider .thunk {position: absolute;left: 100px;top: -4px;width: 10px;height: 6px;z-index: 122;}.slider .block {width: 16px;height: 16px;border-radius: 50%;background: rgba(255, 255, 255, 1);transition: 0.2s all;}.slider .block:hover {transform: scale(1.1);opacity: 0.6;}</style>

组件使用

 <slisd :min="0" :max="100" :value="50" :isDrag="true" bgColor="#4ab157"></slisd>

本篇文章就介绍到这里,如果想要学习更多vue系列知识,点击关注博主