基于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. svg基础--基本语法与标签

    svg系列–基础 这里会总结svg的基础知识和一些经典的案例. svg简介 SVG(Scalable Vector Graphics)is an XML-based Language for crea ...

  2. 对CROS OPTIONS预检请求的一些思考

    前后端分离模大势所趋,跨域问题更是老生常谈. 问题背景: 浏览器最基本的安全规范-同源策略.所谓同源是指域名.协议.端口相同.不同源的浏览器脚本(javascript.ActionScript.can ...

  3. 2020 年度编程语言排行榜出炉!C 语言称霸,Java 遭遇滑铁卢…….

    最近,TIOBE 发布了过去一年的编程语言排行榜: 数据来源TIOBE: https://www.tiobe.com/tiobe-index/ TIOBE介绍: TIOBE编程语言索引是编程语言流行程 ...

  4. 关于Objects类的getClass方法为什么可以得到子类的地址的思考

    这一段时间,总是很纠结为什么Objects中的getClass方法可以返回包含子类地址信息的东西(我不确定返回值类型). 因为在Java中,我们定义的父类,我想破脑袋也想不出怎么可以得到子类的信息. ...

  5. LeetCode 面试题16.18.模式匹配

    模式匹配 题目: 你有两个字符串,即pattern和value. pattern字符串由字母"a"和"b"组成,用于描述字符串中的模式.例如,字符串" ...

  6. 【分享】wdcp服务器管理系统常用维护工具

    wdcp (WDlinux Control Panel) 是一套用PHP开发的Linux服务器管理系统,类似国外流行的cpanel,旨在易于使用和管理Linux服务器,可以在线通过网页管理服务器和虚拟 ...

  7. react项目中实现搜索关键字呈现高亮状态(一)

    最近有个需求,在一个react项目中,实现搜索关键字呈现高亮状态.这个在普通的html文件中还好操作些,在react项目中有点懵逼了,因为react项目中很少操作dom,有点无从下手.但最后还是实现了 ...

  8. 【函数分享】每日PHP函数分享(2021-1-7)

    ltrim() 删除字符串开头的空白字符(或其他字符). string ltrim ( string $str[, string $character_mask]) 参数描述str 输入的字符串. c ...

  9. layui城市三级联动(fesiong / layarea)

    安装 GitHub下载地址:https://github.com/fesiong/layarea.git 使用(html+js) 1. html部分 整个选择器需要使用一个父标签包裹,如下使用了id= ...

  10. 【Spring】Spring中的Bean - 1、Baen配置

    Bean配置 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 什么是Spring中的Bean? Spring可以被看作是一个 ...