基于Vue3.0构建PC桌面端自定义美化滚动条组件V3Scroll。

前段时间有分享一个Vue3 PC网页端弹窗组件,今天带来最新开发的Vue3.0版虚拟滚动条组件。

V3Scroll 使用vue3.x开发的轻量级自定义美化滚动条组件。功能效果基本和之前的vue2版保持一致。支持是否自动隐藏滚动条、自定义滚动条尺寸、颜色及层级等功能。

功能效果类似饿了么el-scrollbar组件。并且支持监听DOM尺寸改变,动态更新滚动条。

◆ 快速引入

main.js中全局引入滚动条v3scroll组件。

import { createApp } from 'vue'
import App from './App.vue'
import './index.css' // 引入滚动条组件v3scroll
import V3Scroll from './components/v3scroll' createApp(App).use(V3Scroll).mount('#app')

◆ 使用组件

通过  <v3-scroll>...</v3-scroll>  包裹内容块,即可快速实现一个精致的替代原生滚动条组件。

<!-- //自定义参数 -->
<v3-scroll size="12" color="#a96950" zIndex="2021">
<p>这里显示自定义内容!</p>
</v3-scroll> <!-- //scroll事件处理 -->
<v3-scroll @scroll="handleScroll">
<p>这里显示自定义内容!</p>
</v3-scroll>

◆ 编码实现

v3scroll支持如下参数自定义配置。

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

v3scroll组件模板

<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']" @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']" @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>

注意:vue3.0中自定义指令directive和vue2中有些不一样。

// vue 2.x
const MyDirective = {
bind(el, binding, vnode, prevVnode) {},
inserted() {},
update() {},
componentUpdated() {},
unbind() {}
} // vue 3.x
const MyDirective = {
beforeMount(el, binding, vnode, prevVnode) {},
mounted() {},
beforeUpdate() {},
updated() {},
beforeUnmount() {},
unmounted() {}
}

下面介绍下在vue3.0中使用自定义指令。

// Vue3中自定义指令 - 监听DOM尺寸变化
directives: {
'resize': {
beforeMount: 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);
},
unmounted: function(el) {
clearInterval(el.__vueReize__);
}
}
}
/**
* @Desc Vue3.0虚拟滚动条组件V3Scroll
* @Time andy by 2021-01
* @About Q:282310962 wx:xy190310
*/
<script>
import { onMounted, ref, reactive, toRefs, nextTick } from 'vue'
import domUtils from './utils/dom'
export default {
props: {
// ...
}, /**
* Vue3.x自定义指令写法
*/
// 监听DOM尺寸变化
directives: {
'resize': {
beforeMount: 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);
},
unmounted: function(el) {
clearInterval(el.__vueReize__);
}
}
},
setup(props, context) {
const ref__box = ref(null)
const ref__wrap = ref(null)
const ref__barX = ref(null)
const ref__barY = ref(null) const data = reactive({
barWidth: 0, // 滚动条宽度
barHeight: 0, // 滚动条高度
ratioX: 1, // 滚动条水平偏移率
ratioY: 1, // 滚动条垂直偏移率
isTaped: false, // 鼠标光标是否按住滚动条
isHover: false, // 鼠标光标是否悬停在滚动区
isShow: !props.autohide, // 是否显示滚动条
}) onMounted(() => {
nextTick(() => {
updated()
})
}) // 鼠标滑入
const handleMouseEnter = () => {
data.isHover = true
data.isShow = true
updated()
} // 鼠标滑出
const handleMouseLeave = () => {
data.isHover = false
data.isShow = false
} // 拖动滚动条
const handleDragThumb = (e, index) => {
const elWrap = ref__wrap.value
const elBarX = ref__barX.value
const elBarY = ref__barY.value data.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
} // ...
} // 点击滚动槽
const handleClickTrack = (e, index) => {
// ...
} // 更新滚动区
const updated = () => {
if(props.native) return
const elBox = ref__box.value
const elWrap = ref__wrap.value
const elBarX = ref__barX.value
const elBarY = ref__barY.value let barSize = domUtils.getScrollBarSize() // 垂直滚动条
if(elWrap.scrollHeight > elWrap.offsetHeight) {
data.barHeight = elBox.offsetHeight **2 / elWrap.scrollHeight
data.ratioY = (elWrap.scrollHeight - elBox.offsetHeight) / (elBox.offsetHeight - data.barHeight)
elBarY.style.transform = `translateY(${elWrap.scrollTop / data.ratioY}px)`
// 隐藏系统滚动条
if(barSize) {
elWrap.style.marginRight = -barSize + 'px'
}
}else {
data.barHeight = 0
elBarY.style.transform = ''
elWrap.style.marginRight = ''
} // 水平滚动条
// ...
} // 滚动区元素/DOM尺寸改变
const handleResize = () => {
// 执行更新操作
} // ... return {
...toRefs(data),
ref__box, ref__wrap, ref__barX, ref__barY, handleMouseEnter, handleMouseLeave,
handleDragThumb, handleClickTrack,
updated, // ...
}
}
}
</script>

支持滚动至指定位置。

<v3-scroll ref="scrollRef">
<p>这里是内容信息!这里是内容信息!</p>
</v3-scroll> <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> setup() {
// 滚动到指定位置
const handleScrollTo = (val) => {
scrollRef.value.scrollTo(val)
}
}

OK,基于Vue3开发自定义模拟滚动条组件就分享到这里。希望大家能喜欢哈~

最后附上一个Vue3.0移动端弹框组件

vue3.0手机端弹层组件:https://www.cnblogs.com/xiaoyan2017/p/14210820.html

vue3系列:vue3.0自定义虚拟滚动条V3Scroll|vue3模拟滚动条组件的更多相关文章

  1. vue2.0 自定义 饼状图 (Echarts)组件

    1.自定义  图表  组件 Echarts.vue <!-- 自定义 echart 组件 --> <template> <div> <!-- echart表格 ...

  2. vue2.0 自定义 图片上传(UpLoader)组件

    1.自定义组件 UpLoader.vue <!-- 上传图片 组件 --> <template> <div class="vue-uploader"& ...

  3. vue3系列:vue3.0自定义弹框组件V3Popup|vue3.x手机端弹框组件

    基于Vue3.0开发的轻量级手机端弹框组件V3Popup. 之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框 ...

  4. Android开发案例 - 自定义虚拟键盘

    所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘,  如下图:    本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚 ...

  5. WPF中实现自定义虚拟容器(实现VirtualizingPanel)

    WPF中实现自定义虚拟容器(实现VirtualizingPanel) 在WPF应用程序开发过程中,大数据量的数据展现通常都要考虑性能问题.有下面一种常见的情况:原始数据源数据量很大,但是某一时刻数据容 ...

  6. vue.js2.0 自定义组件初体验

    理解 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况 ...

  7. Spring 系列教程之自定义标签的解析

    Spring 系列教程之自定义标签的解析 在之前的章节中,我们提到了在 Spring 中存在默认标签与自定义标签两种,而在上一章节中我们分析了 Spring 中对默认标签的解析过程,相信大家一定已经有 ...

  8. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  9. 实战:ADFS3.0单点登录系列-ADFS3.0安装配置

    本文为系列第三章,主要讲下ADFS3.0的安装和配置.本文和前面的文章是一个系列,因此有些地方是有前后关联,比如本文中使用的通配符证书就是第二篇讲解的,因此需要连贯的进行阅读. 全文目录如下: 实战: ...

随机推荐

  1. docker 安装 运行 卸载

    一.卸载docker 安装时使用什么工具安装的docker就用什么工具卸载docker: 1.yum卸载docker 查看已安装的docker yum list installed | grep do ...

  2. jQuery 库中的 $() 是什么?

    概述: $() 函数是 jQuery() 函数的别称. $() 函数用于将任何对象包裹成 jQuery 对象,接着就被允许调用定义在 jQuery 对象上的多个不同方法. 可以将一个选择器字符串传入 ...

  3. C#设计模式——建造者模式(Builder Pattern)

    1.建造者模式简介 1.1>.定义 建造者模式(Builder)将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 1.2>.使用频率  中低 1.3>.原型模式应用 ...

  4. JavaScript--总结三(数组和函数)

    数组 数组的概念: 将多个元素(通常是同一类型)按照一定顺序排列放到一个集合中,这个集合称之为数组---简(一组有序的数据) 数组的作用:可以一次性存储多个数据 数组的定义: 1.通过构造函数创建数组 ...

  5. windows server 2012 R2里IIS配置.net core2.1遇到的坑

    首先刚接触.net core不久,在本地也是简单写点测试程序,没遇到过什么问题,感觉还行,最近朋友搞了个asp.net core2.1的程序,让我给他服务器配置一下,我想这都跨平台了有什么难的吗?拿来 ...

  6. 最实用的visual studio插件,值得收藏!

    1.ReSharper(VS必装,代码重构.代码修正功能) ReSharper 是一个JetBrains公司出品的著名的代码生成工具.其能帮助Microsoft Visual Studio成为一个更佳 ...

  7. Modbus 协议图文详解

    1.概论 Modbus是一种串行通信协议,由于其协议简单易用,且没有版权要求,目前已经成为工业领域通信协议的实时标准.ModBus协议是又施耐德电气的前身Modicon公司在1979年提出的.Modb ...

  8. PostgreSQL WAL日志详解

    wal日志即write ahead log预写式日志,简称wal日志.wal日志可以说是PostgreSQL中十分重要的部分,相当于oracle中的redo日志. 当数据库中数据发生变更时:chang ...

  9. 你一定需要知道的高阶JAVA枚举特性!

    JAVA枚举,比你想象中还要有用! 我经常发现自己在Java中使用枚举来表示某个对象的一组潜在值. 在编译时确定类型可以具有什么值的能力是一种强大的能力,它为代码提供了结构和意义. 当我第一次了解枚举 ...

  10. 【Java基础】基本语法-变量与运算符

    基本语法-变量与运算符 关键字和保留字 关键字定义:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词). 关键字特点:关键字中所有字母都为小写. 用于定义数据类型:class.interf ...