currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3

 2021-07-06 5:40    77  

今天给大家分享一个最新开发的Vue3自定义模拟滚动组件v3scrollcurrentstyle。

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

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

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

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

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

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

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

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

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

currentstyle:Vue3.0系列:vue3定制美化滚动条组件v3scroll

通过简单的<v3-scroll></v3-scroll>裹住内容块,即可快速生成一个精致的仿原生滚动条。

引入组件在main.js中整体引入组件。

import { createApp } from 'vue'import App from './App.vue'import './index.css'// 引入滚动条组件v3scrollimport V3Scroll from './components/v3scroll'createApp(App).use(V3Scroll).mount('#app')快速使用<v3-scroll :native="true"> <img src="://cn.vuejs.org/images/logo.png" style="max-width:100%;" /> <p>这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p></v3-scroll>

<v3-scroll size="12px"> <img src="://cn.vuejs.org/images/logo.png" style="height:180px" /> <img src="://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="://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端模拟滚动条就分享到这里。感谢大家的阅读!

本文标签:滚动组件

原文链接:https://www.xgfox.com/bcrm/476.html

本文版权:如无特别标注,本站文章均为原创。