vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)
vue修改滚动条样式的方法(vue3定制美化滚动条组件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 :native="true"> <img src="https://cn.vuejs.org/images/logo.png" style="max-width:100%;" /> <p>这里是内容信息!这里是内容信息!这里
今天给大家分享一个最新开发的Vue3自定义模拟滚动条组件v3scroll。
V3Scroll 基于vue3.0开发的轻量级PC端虚拟滚动条组件。支持是否自动隐藏、自定义大小、颜色及层叠等功能。
开发灵感来自于之前的vue2版自定义滚动条组件。借鉴了elementPlus滚动条设计。
vue2.x自定义桌面端滚动条组件
v3scroll同样支持垂直/水平滚动条。并且在功能效果上和之前vue2版保持一致。
通过简单的<v3-scroll></v3-scroll>裹住内容块,即可快速生成一个精致的仿原生滚动条。
引入组件在main.js中整体引入组件。
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 :native="true">
<img src="https://cn.vuejs.org/images/logo.png" style="max-width:100%;" />
<p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p>
</v3-scroll>
<v3-scroll size="12px">
<img src="https://cn.vuejs.org/images/logo.png" style="height:180px" />
<img src="https://cn.vuejs.org/images/logo.png" style="height:180px" />
<p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p>
</v3-scroll>
- 参数配置
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' {ishide: !isShow}]" @mousedown="handleClickTrack($event 0)">
<div class="vscroll__thumb" ref="ref__barY" @mousedown="handleDragThumb($event 0)"></div>
</div>
<div :class="['vscroll__bar horizontal' {ishide: !isShow}]" @mousedown="handleClickTrack($event 1)">
<div class="vscroll__thumb" ref="ref__barX" @mousedown="handleDragThumb($event 1)"></div>
</div>
</div>
</template>
- v3scroll逻辑处理
<script>
import { onMounted ref reactive toRefs nextTick } from 'vue'
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
})
// 鼠标滑入
const handleMouseEnter = () => {
data.isHover = true
data.isShow = true
updated()
}
// 鼠标滑出
const handleMouseLeave = () => {
data.isHover = false
if(!data.isTaped && props.autohide) {
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)`
}else {
data.barHeight = 0
elBarY.style.transform = ''
elWrap.style.marginRight = ''
}
// 水平滚动条
// ...
}
// 滚动区元素/DOM尺寸改变
const handleResize = () => {
updated()
}
// 鼠标滚动
const handleScroll = (e) => {
context.emit('scroll' e)
updated()
}
const scrollTo = (dir) => {
const elWrap = ref__wrap.value
const elBarY = ref__barY.value
nextTick(() => {
elWrap.scrollTop = (dir == 'top') ? 0 : (dir == 'bottom') ? elWrap.scrollHeight : parseInt(dir)
elBarY.style.transform = `translateY(${elWrap.scrollTop / data.ratioY}px)`
})
}
return {
...toRefs(data)
ref__box
ref__wrap
ref__barX
ref__barY
handleMouseEnter
handleMouseLeave
handleDragThumb
handleClickTrack
updated
handleResize
handleScroll
scrollTo
}
}
}
</script>
<v3-scroll @scroll="handleScroll">
<p><img src="https://cn.vuejs.org/images/logo.png" style="height:250px;" /></p>
<p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p>
</v3-scroll>
setup() {
// 监听滚动事件
const handleScroll = (e) => {
data.scrollTop = e.target.scrollTop
// 判断滚动状态
if(e.target.scrollTop == 0) {
data.scrollStatus = '到达顶部'
} else if(e.target.scrollTop e.target.offsetHeight >= e.target.scrollHeight) {
data.scrollStatus = '到达底部'
}else {
data.scrollStatus = '滚动中....'
}
}
// ...
}
好了,基于vue3.0实现pc端模拟滚动条就分享到这里。感谢大家的阅读!