Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

  • A+
所属分类:Web前端
摘要

基于vue.js开发的小巧PC端自定义滚动条组件VScroll。 前段时间有给大家分享一个vue桌面端弹框组件,今天再分享最近开发的一个vue pc端自定义滚动条组件。

基于vue.js开发的小巧PC端自定义滚动条组件VScroll。

前段时间有给大家分享一个vue桌面端弹框组件,今天再分享最近开发的一个vue pc端自定义滚动条组件。

vscroll 一款基于vue2.x开发的网页端轻量级超小巧自定义美化滚动条组件。支持是否原生滚动条、鼠标移出是否自动隐藏、自定义滚动条尺寸及颜色等功能。

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

组件在设计开发之初借鉴了 el-scrollbar 及 vuebar 等组件设计思想。

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

通过简单的标签写法  <v-scroll>...</v-scroll>  即可快速生成一个漂亮的替换原生滚动条。

参数配置

props: {     // 是否显示原生滚动条     native: Boolean,     // 是否自动隐藏滚动条     autohide: Boolean,     // 滚动条尺寸     size: { type: [Number, String], default: '' },     // 滚动条颜色     color: String,     // 滚动条层级     zIndex: null },

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

◆ 引入组件

在main.js中引入滚动条组件VScroll。

 import VScroll from './components/vscroll' 

 Vue.use(VScroll) 

◆ 快速使用

** 在使用前需要设置v-scroll外层div容器的宽度或高度。

<!-- 设置原生滚动条 --> <v-scroll native>     <img src="https://cn.vuejs.org/images/logo.png" style="max-width:100%;" />     <p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p> </v-scroll>  <!-- 设置自定义参数 --> <v-scroll autohide size="10" color="#f90" zIndex="2020">     <img src="https://cn.vuejs.org/images/logo.png" style="max-width:100%;" />     <p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p> </v-scroll>

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

◆ 实现过程

vscroll组件目录结构如下:

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

<!-- //VScroll 自定义滚动条模板 --> <template>   <div class="vui__scrollbar" ref="ref__box" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" v-resize="handleResize">     <div :class="['vscroll__wrap', {native: native}]" ref="ref__wrap" @scroll="handleScroll">       <div class="vscroll__view" v-resize="handleResize">         <slot />       </div>     </div>     <!-- //滚动条 -->     <div :class="['vscroll__bar vertical', {ishide: !isShow}]" @mousedown="handleClickTrack($event, 0)" :style="{'width': parseInt(size)>=0 ? parseInt(size)+'px' : '', 'z-index': parseInt(zIndex)>=0 ? parseInt(zIndex) : ''}">       <div class="vscroll__thumb" ref="ref__barY" :style="{'background': color, 'height': barHeight+'px'}" @mousedown="handleDragThumb($event, 0)"></div>     </div>     <div :class="['vscroll__bar horizontal', {ishide: !isShow}]" @mousedown="handleClickTrack($event, 1)" :style="{'height': parseInt(size)>=0 ? parseInt(size)+'px' : '', 'z-index': parseInt(zIndex)>=0 ? parseInt(zIndex) : ''}">       <div class="vscroll__thumb" ref="ref__barX" :style="{'background': color, 'width': barWidth+'px'}" @mousedown="handleDragThumb($event, 1)"></div>     </div>   </div> </template>

在vue中如何通过指令directtive函数来监听元素/DOM尺寸变化?

非常简单,写一个轮询自定义指令就行。这里就直接监听滚动区DOM宽/高变化来动态更新滚动条状态。

// 监听元素/DOM尺寸变化 directives: {     'resize': {         bind: function(el, binding) {             let width = '', height = '';             function get() {             const elStyle = el.currentStyle ? el.currentStyle : document.defaultView.getComputedStyle(el, null);             if (width !== elStyle.width || height !== elStyle.height) {                 binding.value({width, height});             }             width = elStyle.width;             height = elStyle.height;             }             el.__vueReize__ = setInterval(get, 16);         },         unbind: function(el) {             clearInterval(el.__vueReize__);         }     } },

/**  * @Desc     vue.js自定义滚动条直接VScroll  * @Time     andy by 2020-11-30  * @About    Q:282310962  wx:xy190310  */ <script>   import domUtils from './utils/dom'   export default {     props: {       // 是否显示原生滚动条       native: Boolean,       // 是否自动隐藏滚动条       autohide: Boolean,       // 滚动条尺寸       size: { type: [Number, String], default: '' },       // 滚动条颜色       color: String,       // 滚动条层级       zIndex: null     },     data() {       return {         barWidth: 0,            // 滚动条宽度         barHeight: 0,           // 滚动条高度         ratioX: 1,              // 滚动条水平偏移率         ratioY: 1,              // 滚动条垂直偏移率         isTaped: false,         // 鼠标光标是否按住滚动条         isHover: false,         // 鼠标光标是否悬停在滚动区         isShow: !this.autohide, // 是否显示滚动条       }     },     mounted() {       this.$ref__box = this.$refs.ref__box       this.$ref__wrap = this.$refs.ref__wrap       this.$ref__barY = this.$refs.ref__barY       this.$ref__barX = this.$refs.ref__barX       this.$nextTick(this.updated)     },     // ...     methods: {       // 鼠标移入       handleMouseEnter() {         this.isHover = true         this.isShow = true         this.updated()       },        // 鼠标移出       handleMouseLeave() {         this.isHover = false         this.isShow = false       },        // 拖动滚动条       handleDragThumb(e, index) {         let _this = this         this.isTaped = true         let c = {}         // 阻止默认事件         domUtils.isIE() ? (e.returnValue = false, e.cancelBubble = true) : (e.stopPropagation(), e.preventDefault())         document.onselectstart = () => false          if(index == 0) {           c.dragY = true           c.clientY = e.clientY         }else {           c.dragX = true           c.clientX = e.clientX         }          domUtils.on(document, 'mousemove', function(evt) {           if(_this.isTaped) {             if(c.dragY) {               _this.$ref__wrap.scrollTop += (evt.clientY - c.clientY) * _this.ratioY               _this.$ref__barY.style.transform = `translateY(${_this.$ref__wrap.scrollTop / _this.ratioY}px)`               c.clientY = evt.clientY             }             if(c.dragX) {               _this.$ref__wrap.scrollLeft += (evt.clientX - c.clientX) * _this.ratioX               _this.$ref__barX.style.transform = `translateX(${_this.$ref__wrap.scrollLeft / _this.ratioX}px)`               c.clientX = evt.clientX             }           }         })         domUtils.on(document, 'mouseup', function() {           _this.isTaped = false                      document.onmouseup = null;           document.onselectstart = null         })       },        // 点击滚动槽       handleClickTrack(e, index) {         console.log(index)       },        // 更新滚动区       updated() {         if(this.native) return          // 垂直滚动条         if(this.$ref__wrap.scrollHeight > this.$ref__wrap.offsetHeight) {           this.barHeight = this.$ref__box.offsetHeight **2 / this.$ref__wrap.scrollHeight           this.ratioY = (this.$ref__wrap.scrollHeight - this.$ref__box.offsetHeight) / (this.$ref__box.offsetHeight - this.barHeight)           this.$ref__barY.style.transform = `translateY(${this.$ref__wrap.scrollTop / this.ratioY}px)`         }else {           this.barHeight = 0           this.$ref__barY.style.transform = ''           this.$ref__wrap.style.marginRight = ''         }          // 水平滚动条         ...       },        // 滚动区元素/DOM尺寸改变       handleResize() {         // 更新滚动条状态       },        // ...     }   } </script>

滚动至指定位置

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

<p>     <span class="vs__btn" @click="handleScrollTo('top')">滚动至顶部</span>     <span class="vs__btn" @click="handleScrollTo('bottom')">滚动至底部</span>     <span class="vs__btn" @click="handleScrollTo(150)">滚动至150px</span> </p>  <v-scroll ref="vscrollRef">     <img src="https://cn.vuejs.org/images/logo.png" style="height:180px;" />     <p><img src="https://cn.vuejs.org/images/logo.png" style="height:350px;" /></p>     <p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p> </v-scroll>

// 滚动到指定位置 handleScrollTo(val) {     this.$refs.vscrollRef.scrollTo(val); },

监听scroll滚动事件

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

<v-scroll @scroll="handleScroll">     <img src="https://cn.vuejs.org/images/logo.png" style="height:180px;margin-right:10px;" />     <br />     <p><img src="https://cn.vuejs.org/images/logo.png" style="height:250px;" /></p>     <p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p> </v-scroll>

// 监听滚动事件 handleScroll(e) {     this.scrollTop = e.target.scrollTop     // 判断滚动状态     if(e.target.scrollTop == 0) {         this.scrollStatus = '到达顶部'     } else if(e.target.scrollTop + e.target.offsetHeight >= e.target.scrollHeight) {         this.scrollStatus = '到达底部'     }else {         this.scrollStatus = '滚动中....'     } },

OK,以上就是基于vue.js实现自定义滚动条组件。希望能对大家有些帮助!?

Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

最后附上vue.js桌面端弹出框组件

vue pc端弹窗组件:https://www.cnblogs.com/xiaoyan2017/p/13913860.html