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


Posted in Vue.js onDecember 01, 2020

前言

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

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

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

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

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

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

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

参数配置

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

Vue.js桌面端自定义滚动条组件之美化滚动条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桌面端自定义滚动条组件之美化滚动条VScroll

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

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

◆ 实现过程

vscroll组件目录结构如下:

Vue.js桌面端自定义滚动条组件之美化滚动条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桌面端自定义滚动条组件之美化滚动条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桌面端自定义滚动条组件之美化滚动条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桌面端自定义滚动条组件之美化滚动条VScroll的文章就介绍到这了,更多相关Vue.js美化滚动条VScroll内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue3.0中setup使用(两种用法)
Dec 02 Vue.js
vuex的使用步骤
Jan 06 Vue.js
vue watch监控对象的简单方法示例
Jan 07 Vue.js
学习 Vue.js 遇到的那些坑
Feb 02 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
vue项目实现分页效果
Mar 24 Vue.js
vue中data改变后让视图同步更新的方法
Mar 29 Vue.js
如何理解Vue前后端数据交互与显示
May 10 Vue.js
vue组件的路由高亮问题解决方法
May 11 Vue.js
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
解决vue中provide inject的响应式监听
Apr 19 Vue.js
Vue ECharts实现机舱座位选择展示功能
May 15 Vue.js
vue开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 #Vue.js
vue实现表格合并功能
Dec 01 #Vue.js
vue element实现表格合并行数据
Nov 30 #Vue.js
Vue Elenent实现表格相同数据列合并
Nov 30 #Vue.js
vue中defineProperty和Proxy的区别详解
Nov 30 #Vue.js
详解Vue 的异常处理机制
Nov 30 #Vue.js
ESLint 是如何检查 .vue 文件的
Nov 30 #Vue.js
You might like
hadoop中一些常用的命令介绍
2013/06/19 PHP
php生成txt文件标题及内容的方法
2014/01/16 PHP
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
10款PHP开源商城系统汇总介绍
2015/07/23 PHP
MAC下通过改apache配置文件切换php多版本的方法
2017/04/26 PHP
发一个自己用JS写的实用看图工具实现代码
2008/07/26 Javascript
js函数的引用, 关于内存的开销
2012/09/17 Javascript
js和jquery使按钮失效为不可用状态的方法
2014/01/26 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
JavaScript实现重置表单(reset)的方法
2015/04/02 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
js实现把图片的绝对路径转为base64字符串、blob对象再上传
2016/12/29 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
vue组件 keep-alive 和 transition 使用详解
2019/10/11 Javascript
vue大型项目之分模块运行/打包的实现
2020/09/21 Javascript
Python用sndhdr模块识别音频格式详解
2018/01/11 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python实现感知器算法(批处理)
2019/01/18 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
利用Python如何画一颗心、小人发射爱心
2021/02/21 Python
html5 canvas实现给图片添加平铺水印
2019/08/20 HTML / CSS
L’AGENCE官网:加州女装品牌
2018/06/03 全球购物
秸秆管理实施方案
2014/03/15 职场文书
《蜗牛的奖杯》教后反思
2014/04/24 职场文书
社区巾帼文明岗事迹材料
2014/06/03 职场文书
数学兴趣小组活动总结
2014/07/08 职场文书
2014年酒店工作总结范文
2014/11/17 职场文书
2015年药房工作总结
2015/04/25 职场文书
企业计划生育责任书
2015/05/09 职场文书
2016年“5.12”护士节致辞
2015/07/31 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
《青山不老》教学反思
2016/02/22 职场文书
Python使用UDP实现720p视频传输的操作
2021/04/24 Python