精华内容
下载资源
问答
  • Vue3-Scroll 基于vue3.0构建的桌面端虚拟美化滚动条组件。 一款基于vue3.x构建的pc端自定义模拟滚动条|vue3.0美化滚动条组件。支持监听DOM尺寸变化、是否原生滚动、是否自动隐藏滚动条、自定义尺寸/颜色及层级等...

    Vue3-Scroll 基于vue3.0构建的桌面端虚拟美化滚动条组件。

    一款基于vue3.x构建的pc端自定义模拟滚动条|vue3.0美化滚动条组件。支持监听DOM尺寸变化、是否原生滚动、是否自动隐藏滚动条、自定义尺寸/颜色及层级等功能。

    引入组件

    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 size="10" color="#ff5588" zIndex="1000">
        <p>显示自定义内容!</p>
    </v3-scroll>
    
    <!-- //scroll事件处理 -->
    <v3-scroll @scroll="handleScroll">
        <p>显示自定义内容!</p>
    </v3-scroll>

    效果和饿了么滚动条组件有些类似。并且支持监听DOM尺寸改变,动态更新滚动条

    参数配置

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

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

    组件模板

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

    自定义指令directive

    vue2.x和vue3中使用自定义指令有些不一样。

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

    v3scroll核心逻辑处理。

    /**
     * @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 @scroll="handleScroll">
    	<p><img src="https://cn.vuejs.org/images/logo.png" style="height:250px;" /></p>
    	<p>内容信息!这里是内容信息!这里是内容信息!这里是内容信息!这里是内容信息!</p>
    </v3-scroll>
    
    setup(){
    	// 监听滚动事件
    	handleScroll(e) {
    		this.scrollTop = e.target.scrollTop
    		// 判断滚动状态
    		if(e.target.scrollTop == 0) {
    			this.scrollStatus = '到达顶部'
    		} else if(e.target.scrollTop + e.target.offsetHeight >= e.target.scrollHeight) {
    			this.scrollStatus = '到达底部'
    		}else {
    			this.scrollStatus = '滚动中....'
    		}
    	}
    	
    	// ...
    }

    Okay,基于vue3.x开发自定义滚动条组件就分享到这里。希望对大家有些帮助!💪🏻

    vue3.0网页端弹窗组件V3Layer

     

    展开全文
  • Vuescroll – 一个基于Vue虚拟滚动

    千次阅读 2018-09-26 14:05:52
    以前接触过一个后端管理系统, 叫H+, 偶尔发现它用的是左侧菜单没有滚动条, 于是, 我仔细查看dom, 发现H+ 左侧菜单的旁边有一个小的DIV, 我拖动的, 菜单竟然也能滚动, 我明白了, 这是用的虚拟滚动条, 我...

    灵感来源

    以前接触过一个后端管理系统, 叫H+, 偶尔发现它用的是左侧菜单没有滚动条, 于是, 我仔细查看dom, 发现H+ 左侧菜单的旁边有一个小的DIV, 我拖动的, 菜单竟然也能滚动, 我明白了, 这是用的虚拟滚动条, 我感觉这个挺不错的, 后来查看这个虚拟滚动条的源码, 发现是一个款叫做SlimScroll的基于jquery的库。由于我对Vue比较熟悉,所以,我想用Vue做一个类似的。

    不断踩坑

    一开始用slimScroll的方法并不理想, slimscroll的滚动内容的方法是:

    监听滚轮事件,根据滚动每次滚动的距离,然后计算内容滑动的距离。
    监听拖动滚动把手的事件,通过拖动滚动把手的距离来滑动内容的距离。
    这有个2致命的缺点:

    不能平滑的滚动, 什么叫不能平滑地滚动? 就是滚动到目标的点没有一个过度的效果, 一下子就突然到目的地了。
    在手机端上的时候, 当手指滑动离开滚动内容的时候, 内容不能继续滚动!
    这两点带来了极差的UI体验!

    后来, 我无意中发现了element-ui也是使用了虚拟滚动条, 并且效果很好, 尤其是在手机端滑动, 每次滑动结束手离开屏幕都能继续滑行一段距离, 比slimscroll效果要好,于是我就去element-ui的github上翻scrollbar的源码, 通过阅读源码, 我发现element-ui触发滚动的时机是在onscroll的时候, 也就是说, 把滚动内容的父元素设置为overflow:scroll, 然后监听父元素的onScroll事件, 在onScroll事件的callback里面移动滚动内容即可。 经过我的一番改进, 终于能做到和element-ui滚动条滚动的一个效果了。

    滚动条升级

    后来,我又接触到了几个不错的, 并把它们的特点加进来了。 如element-resize-detector, scroller, smooth-scroll, bertter-scroll等等。 现在的Vuescroll已经升级为一个功能强大的滚动条了。

    它的基本特点有:

    为Vue量身打造,拥有Vue响应式的特点。
    可以通过选择不同的模式来运行在PC端或者手机上:

    native

    模式: 类似于原生的滚动条,但是可以自定义滚动条样式,使用于PC端用户。

    slide

    模式: 允许你用手指或鼠标滑动内容, 可以滑动超出边界范围,适用于移动端端用户。

    pure-native

    模式: 滚动条使用原生的滚动条,适用于喜欢原生滚动条的用户。
    检测滚动内容发生尺寸变化并自动更新滚动条。
    通过使用 不同的滚动动画来平滑滚动。
    下拉-刷新 (拉倒顶部并拉出边界开始刷新列表)
    上推-加载 (推到底部并且退出边界开始加载列表)
    能够放大或者缩小滚动的内容.
    分页 (每次滑动整个页面)
    截断 (每次滑动一个用户定义的距离)
    能够禁止X或Y方向上的滚动。
    能够设置滚动条是否保持显示。
    能够设置滚动条,轨道的颜色和透明度。
    能够设置滚动条,轨道的位置。
    能够自定义内容的标签 (也就是说你能够设置内容的标签为一个组件)
    总的来说,Vuescroll不仅仅只一个滚动条, 你可以用它制作一个轮播图、时间选择器、能够自动侦测内容发生变化的一个插件等等。

    展开全文
  • /*** @Desc Vue3.0虚拟滚动条组件V3Scroll* @Time andy by 2021-01* @About Q:282310962 wx:xy190310*/import { onMounted, ref, reactive, toRefs, nextTick } from'vue'import domUtils from'./utils/dom'exp...

    /**

    * @Desc Vue3.0虚拟滚动条组件V3Scroll

    * @Time andy by 2021-01

    * @About Q:282310962 wx:xy190310*/

    props: {//...

    },/**

    * Vue3.x自定义指令写法*/

    //监听DOM尺寸变化

    directives: {'resize': {

    beforeMount:function(el, binding) {

    let width= '', height = '';functionget() {

    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= truedata.isShow= trueupdated()

    }//鼠标滑出

    const handleMouseLeave = () =>{

    data.isHover= falsedata.isShow= false}//拖动滚动条

    const handleDragThumb = (e, index) =>{

    const elWrap=ref__wrap.value

    const elBarX=ref__barX.value

    const elBarY=ref__barY.value

    data.isTaped= truelet c={}//阻止默认事件

    domUtils.isIE() ? (e.returnValue = false, e.cancelBubble = true) : (e.stopPropagation(), e.preventDefault())

    document.onselectstart= () => false

    if(index == 0) {

    c.dragY= truec.clientY=e.clientY

    }else{

    c.dragX= truec.clientX=e.clientX

    }//...

    }//点击滚动槽

    const handleClickTrack = (e, index) =>{//...

    }//更新滚动区

    const updated = () =>{if(props.native) returnconst 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= 0elBarY.style.transform= ''elWrap.style.marginRight= ''}//水平滚动条

    //...

    }//滚动区元素/DOM尺寸改变

    const handleResize = () =>{//执行更新操做

    }//...

    return{

    ...toRefs(data),

    ref__box, ref__wrap, ref__barX, ref__barY,

    handleMouseEnter, handleMouseLeave,

    handleDragThumb, handleClickTrack,

    updated,//...

    }

    }

    }

    展开全文
  • vxe-table vue 目前为止唯一能全能支持虚拟滚动的组件:虚拟列表、虚拟树、横向与纵向虚拟滚动的表格组件 目前主流的数据驱动框架 react、vue …等虽然入门相当简单;例如 vue 中,由于数据双向的原因,需要对数据...

    vxe-table vue 中支持虚拟滚动组件:虚拟列表、虚拟树、横向与纵向虚拟滚动的列表与表格组件

    目前主流的数据驱动框架 react、vue …等虽然上手门槛较低,但是其性能就比原生的 js 差多了;
    例如 vue 中,由于数据双向的原因,需要对数据进行双向监听,从而使渲染性能大幅下降,如果数据量稍微大一点,页面基本上是直接卡死,那么如何解决呢?虚拟组件由此诞生,只渲染当前可视区的内容,其余的收起,当滚动到指定位置时才渲染对应的节点,即时 vue 的双向绑定会损耗性能,由于 dom 节点的大幅减少,也不会对性能造成影响,从而流畅加载。

    可以同时支持虚拟渲染 + 固定列+ 单元格鼠标区域选取…等

    相关说明

    缺点

    • 启用虚拟滚动后 show-overflow,show-header-overflow,show-footer-overflow 参数将根据渲染规则各自触发生效,无法取消;所有单元格比较同等高度,不能用于自适应高度;
    • 不支持展开行以及任何破坏单元格高度的方式
    • 横向虚拟滚动不支持分组表头
    • 当渲染复杂固定列时,同步滚动会有延迟,具体由渲染的复杂度决定

    全局参数

    import VXETable from 'vxe-table'
    
    VXETable.setup({
    	table: {
    		scrollX: {
            	gt: 60
            },
            scrollY: {
            	gt: 100
            }
    	},
    	list: {
            scrollY: {
            	gt: 100
            }
    	}
    })
    

    关闭虚拟滚动

    scroll-x 用于控制横向虚拟滚动,gt 当大于指定条数时自动启用,默认 60,如果 enabled=false 或者 gt=-1 则关闭虚拟滚动
    scroll-y 用于控制纵向虚拟滚动,gt 当大于指定条数时自动启用,默认 100,如果 enabled=false 或者 gt=-1 则关闭虚拟滚动

    <vxe-table :scroll-x="{enabled: false}" :scroll-y="{enabled: false}">
    ...
    </vxe-table>
    

    虚拟列表

    可以将项目中任意的列表渲染成虚拟滚动,从而支持大数据量加载,例如实现下拉框虚拟列表、海量数据列表…等等,对性能大幅提升,滚动非常流畅(理论上最大可以支持 60w 行)
    在这里插入图片描述

    纵向虚拟表格

    表格开启虚拟滚动,对于一次性加载 20w 条数据不是梦(理论上最大可以支持 30w 行)在这里插入图片描述

    横向与纵向虚拟表格

    对于某些特殊的场景,比如产品经理说要把一个表格的列非常多的表格全部加载出来,比如 1w 列头、5w 条数据,对于这种需求如果就需要随时准备砖头(谁提拍谁),就可以试试同时开启横向和纵向虚拟滚动,只会渲染可视区的 tr、td 节点,也能轻松应对(理论上最大可以支持 30w 行)
    在这里插入图片描述

    纵向虚拟树表格

    除了列表之外,那么最复杂的就是树结构了,当一颗树节点非常多的时候,如果都渲染出来,由于是树结构,那么递归的损耗比列表大太多了。别急,好在虚拟树也是支持的,以下渲染 5w 条树节点,依然流畅(理论上最大可以支持 30w 行)

    树的虚拟滚动需要借助一个插件 vxe-table-plugin-virtual-tree
    在这里插入图片描述

    横向与纵向虚拟树表格

    除了以上树的虚拟滚动,如果还要更变态一点,比如要支持 5k 列 5w 行树节点,别急,准备好砖头;理论上还是可以支持的,但是由于目前的数据结构已经到了极限了,涉及 js 运行效率、数据双向的损耗…等,(理论上最大可以支持 30w 行)
    在这里插入图片描述
    到这里就结束了,没错,完了!

    展开全文
  • 1.用Npm引入 npm install vuescroll -S 2.在main.js import vuescroll from 'vuescroll'; Vue.use(vuescroll); 3.效果
  • vxe-table vxe-list vue 实现高性能的虚拟虚拟列表的实现原理:只渲染可视区的 dom 节点,其余不可见的数据卷起来,最大程度的减少 dom 节点,提高渲染性能及流畅性,优点是支持海量数据的渲染;当然也会有缺点:...
  • 众所周知,当节点达到一定数量的时候,前端就会产生很大的性能问题,那么我们应该怎么来改善这种局面呢,没错,就是所谓的虚拟滚动,其实就是几个节点在滚动的时候移来移去,非常的乏味。 其实很早之前就已经研究过...
  • vue-virtualscroll用于虚拟滚动npm的Vuejs库vue-virtualscroll从'vue-virtualscroll'导入VueVirtualScroll {{index}}-{{item.name}} :height [必填]项目的行高@ScrollTop滚动到列表顶部时发出的@reachBottom滚动...
  • 最近项目中有用到vue3中的虚拟滚动,但中间又用到了动态行高。找了找网上的虚拟滚动插件都不太适用,只好自己写了一个乞丐版能满足自己需求的东西。 具体思路 就是将全部数组切分一下,只取渲染的数组,然后滚动时...
  • 本篇文章主要介绍了基于vue.js 2.x的虚拟滚动条的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • vue dom滚动监听 守门员 (vue-recyclist) Infinite scroll list for Vue.js (v2.1+) with DOM recycling. 带有DOM回收的Vue.js(v2.1 +)的无限滚动列表。 View demo 查看演示 Download Source 下载源 安装 ...
  • 虚拟滚动插件 1 背景 一个长列表 Web 页面,如果需要展示成千上万条数据,那么页面中就会有数万甚至数十万的HTML节点,会巨大的消耗浏览器性能,进而给用户造成非常不友好的体验。 主要体现在以下几个方面: ...
  • Vuescroll 是一个基于 vue.js 2.X的虚拟滚动条,它拥有多个模式可供你选择: slide 模式、native 模式和pure-native模式, 并且它还支持定制滚动条的样式,检测内容尺寸变化、能够使内容分页、支持上拉-刷新,下推...
  • 基于Vue.js的强大的虚拟滚动条.zip,A scrolling plugin with a easy getting-start and full configuration for Vue.js.
  • // 计算可视化高度一次能装几个列表, 多设置几个防止滚动时候直接替换 this.showNum = Math.floor(this.viewH / this.itemH) + 4; // 默认展示几个 this.clist = this.list.slice(0, this.showNum);...
  • 要在您的应用程序中显示大量数据,一次加载所有内容不是一个好的解决方案。...此解决方案称为虚拟滚动。使用Vue.js,我们可以使用位于https://www.npmjs.com/package/vue-virtual-scroll-list的vue-virtual-sc...
  • 使用vue实现高性能虚拟滚动组件

    千次阅读 2020-03-22 19:26:44
    <template> <div> <div :style="`height:${viewH}px;overflow-y:scroll;`" @scroll="hanldeScroll"> <div :style="{height:scorllH}"> <div class="item_box...
  • vue大数据滚动组件

    千次阅读 2019-11-17 14:01:29
    最近在开发项目中遇到一个需求,需要实现一个渲染上千条数据的列表,但如果一次渲染出这么多DOM节点对性能会是很大的消耗。于是上github找了一下相关的优化方案,最终找到一个组件...参考了vue-virtu...
  • 在本文中,我们将研究如何添加日期和时间选择器以及虚拟滚动列表的最佳包。 Vue日期时间选择器 Vue dateTime Picker允许我们在Vue应用程序中添加日期和时间选择器。 要安装它,我们运行: 现在我们可以用它写: ...
  • 如何实现vue滚动条,滚动到置顶位置,如何实现平滑的动画效果。 ``` methods:{ Scroll(){ document.documentElement.scrollTop = document.getElementById('header').offsetWidth; }, } ``` 我滚动的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,206
精华内容 1,282
关键字:

vue虚拟滚动

vue 订阅