快捷搜索:  汽车  科技

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

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(1)

V3Scroll 基于vue3.0开发的轻量级PC端虚拟滚动条组件。支持是否自动隐藏、自定义大小、颜色及层叠等功能。

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(2)

开发灵感来自于之前的vue2版自定义滚动条组件。借鉴了elementPlus滚动条设计。

vue2.x自定义桌面端滚动条组件

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(3)

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(4)

v3scroll同样支持垂直/水平滚动条。并且在功能效果上和之前vue2版保持一致。

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(5)

通过简单的<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>

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(6)

<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>

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(7)

编码实现
  • 参数配置

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>

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(8)

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(9)

<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 = '滚动中....' } } // ... }

vue修改滚动条样式的方法(vue3定制美化滚动条组件v3scroll)(10)

好了,基于vue3.0实现pc端模拟滚动条就分享到这里。感谢大家的阅读!

猜您喜欢: