vue虚拟化列表封装的实现

目录
  • vue虚拟化列表封装
    • 将下面代码复制一份到自己的项目中
  • vue虚拟列表-vue-virtual-scroll-list
    • 使用场景
    • 安装
    • 使用

vue虚拟化列表封装

将下面代码复制一份到自己的项目中

<template>
    <div class="scrollParent" ref="scrollContent" @scroll="handleScroll">
        <div :style="blankFillStyle">
            <div v-for="item,index in showDataList" :key="index">
                <slot :everyVirtual="item"></slot>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props:["oneHeight","virtualList"],
    data () {
        return {
            contentSize:"", //可视区域可以展示多少条数据
            startIndex:0, //记录当前滚动的第一个元素的索引
            currentScroll:0,  //记录当前滚动的距离
        }
    },
    methods:{
        // 获取可视区域可以展示多少条
        getContentSize(){
            // 两次取反可以获取到整数部分
            this.contentSize = ~~(this.$refs.scrollContent.offsetHeight / this.oneHeight) + 2;
        },
        // 监听滚动条
        handleScroll(){
            // 持续滚动  减少变量重新赋值  优化处理 只有在到下一个元素节点的时候才会重新给this.statrIndex赋值  避免和this.startIndex相关联的数据再次计算
            this.currentScroll = this.$refs.scrollContent.scrollTop;
            let currentIndex = ~~(this.$refs.scrollContent.scrollTop/this.oneHeight);
            if(this.startIndex == currentIndex){
                return
            }
            this.startIndex = currentIndex;
            if((this.startIndex + this.contentSize - 1)>this.virtualList.length-1){ //说明到达底部了
                this.$emit("scrollEnd")
            }
        }
    },
    activated(){
        this.$nextTick(()=>{
            this.$refs.scrollContent.scrollTop = this.currentScroll;
        })
    },
    computed:{
        endIndex(){ //获取最后一个元素的索引
            let endIndex = this.startIndex + this.contentSize*2;
            if(endIndex>this.virtualList.length-1){
                endIndex = this.virtualList.length-1
            }
            return endIndex;
        },
        showDataList(){
            let startIndex = 0;
            if(this.startIndex<=this.contentSize){
                startIndex = 0;
            }else{
                startIndex = this.startIndex - this.contentSize;
            }
            return this.virtualList.slice(startIndex,this.endIndex);
        },
        blankFillStyle(){
            let startIndex = 0;
            if(this.startIndex<=this.contentSize){
                startIndex = 0;
            }else{
                startIndex = this.startIndex - this.contentSize;
            }
            return{
                paddingTop:startIndex * this.oneHeight + "px",
                paddingBottom:(this.virtualList.length - this.endIndex) * this.oneHeight +"px"
            }
        }
    },
    mounted(){
        window.onresize = this.getContentSize();
        window.orientationchange = this.getContentSize();
    }
}
</script>
<style scoped>
    .scrollParent{
        height: 100%;
        width: 100%;
        overflow-y: auto;
    }
</style>

vue虚拟列表-vue-virtual-scroll-list

使用场景

因为公司做了类似于百度网盘的竞品,所以用户如果上传了很多的文件,就会造成页面DOM元素的过多,然后因为需要操作DOM元素,所以页面会变得很卡。所以用虚拟列表来解决。

安装

安装的话这个插件有2个版本的,一个是1版本,目前更新到2版本了,二版本功能更加的强大。这里使用了1版本,通俗易懂一点。

npm install --save vue-virtual-scroll-list@1.1.3

使用

在单页面中导入

import VirtualList from "vue-virtual-scroll-list";
components: {
    VirtualList,//注册组件
  },
          <div class="content-timeview_box">
            <!-- size代表行高 remain代表一次渲染的数量 -->
            <!-- 出现的问题:1.在时间视图时(文件夹视图只有一个VirtualList不受影响) 一个日期代表一个VirtualList 怎么解决高度问题? -->
            <!-- 如果统一高度?一个日期中的文件数量少于高度 就会出现VirtualList之间的空白问题 -->
            <!-- 应该根据日期下的文件数量来动态的绑定每一个VirtualList的高度 -->
          <VirtualList
          :size="40"
          :remain="17"
          :wclass="vuesrollboxviewClass"
          :tobottom="toBottom"
          style="padding: 0 32px 0 32px"
          :style="{height:itembig.items.length>6?scrollbarheight:'200px'}"
        >
  • toBottom的方法,这个地方就很坑,因为我只能在1.1.3版本中触发这个方法,1版本的其他版本号我没有触发成功,应该还是高度的问题。
  • toBottom:滚动到底部时触发,请求下一组数据
    //滚到底部时触发
    //注:此方法在1.0高版本不兼容,只能在官方文档1.1.3版本中使用
    //@1.1.3
    toBottom() {
      this.infiniteHandler();
    },
:wclass=“vuesrollboxviewClass”

wclass是自定义的class,我这里的业务场景不是每行只有1个数据,从上而下排列下来,而是每行根据分辨率不同,展示5个或6个,所以得计算好一次渲染的个数,需要动态的绑定。

小结:还是需要更熟练的掌握原生JS,虽然有各种各样的框架插件来解决问题,但是碰到业务场景更复杂的时候呢?所以还是要掌握原生JS,具备自己写轮子的能力才行。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用 Vue 实现一个虚拟列表的方法

    因为 DOM 性能瓶颈,大型列表存在难以克服的性能问题. 因此,就有了 "局部渲染" 的优化方案,这就是虚拟列表的核心思想. 虚拟列表的实现,需要重点关注的问题一有以下几点: 可视区域的计算方法 可视区域的 DOM 更新方案 事件的处理方案 下面逐一分解说明. 可视区域计算 可视区域的计算,就是使用当前视口的高度.当前滚动条滚过的距离,得到一个可视区域的坐标区间. 算出可视区域的坐标区间之后,在去过滤出落在该区间内的列表项,这个过程,列表项的坐标也是必须能算出的. 思考以下情况, 我们

  • vue实现虚拟列表功能的代码

    当数据量较大(此处设定为10w),而且要用列表的形式展现给用户,如果我们不做处理的话,在浏览器中渲染10w dom节点,是极其耗费时间的,那我的Macbook air举例,10w条数据渲染出来到能看到页面,需要13秒多(实际应该是10秒左右),如果是用户的话肯定是不会等一个网页十几秒的 我们可以用虚拟列表解决这个问题 一步步来 首先看一下效果 这是data中的数据 data() { return { list: [], // 贼大的数组 li: { // 列表项信息 height: 50, },

  • vxe-list vue 如何实现下拉框的虚拟列表

    目录 vxe-list vue 下拉框的虚拟列表 虚拟列表的实现原理 接下来测试一下 vue虚拟列表实现原理 应用场景 实现思路 基础实现 vxe-list vue 下拉框的虚拟列表 vxe-table vxe-list vue 实现下拉框的虚拟列表 虚拟列表的实现原理 只渲染可视区的 dom 节点,其余不可见的数据卷起来,只会渲染可视区域的 dom 节点,提高渲染性能及流畅性,优点是支持海量数据的渲染:当然也会有缺点:滚动效果相对略差(海量数据与滚动效果的取舍问题就看自己的需求喽): <div

  • vue虚拟化列表封装的实现

    目录 vue虚拟化列表封装 将下面代码复制一份到自己的项目中 vue虚拟列表-vue-virtual-scroll-list 使用场景 安装 使用 vue虚拟化列表封装 将下面代码复制一份到自己的项目中 <template> <div class="scrollParent" ref="scrollContent" @scroll="handleScroll"> <div :style="blankFill

  • vue 组件的封装之基于axios的ajax请求方法

    如下所示: import Vue from 'vue' let service = { url: 'http://host.xxxxx.com/xxx.php' } service.ajaxReuqest = (url, options, type, fileFlag) => { for (const i in options) { if (!options[i] && options[i] !== 0 && (options[i].length &&

  • Vue开发之封装上传文件组件与用法示例

    本文实例讲述了Vue开发之封装上传文件组件与用法.分享给大家供大家参考,具体如下: 使用elementui的 el-upload插件实现图片上传组件 每个项目存在一定的特殊性,所以数据的处理会不同 pictureupload.vue: <template> <div class="pictureupload"> <el-upload :action="baseUrl + '/api/public/image'" list-type=&q

  • 详解Vue中Axios封装API接口的思路及方法

    一.axios的封装 在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中.他有很多优秀的特性,例如拦截请求和响应.取消请求.转换json.客户端防御XSRF等. 在一个项目中我们如果要使用很多接口的话,总不能在每个页面都写满了.get()或者.post()吧?所以我们就要自己手动封装一个全局的Axios网络模块,这样的话就既方便也会使代码量不那么冗余. 安装 > npm install axios //这个

  • vue 公共列表选择组件,引用Vant-UI的样式方式

    此组件用于公共选择组件.引用Vant UI 作为样式 特性: 1.支持动态.静态数据源. 2.支持分页加载. 3.支持模糊搜索. 4.支持单选.多选. 组件源码: <template> <div class="gn-PubSelect"> <van-action-sheet v-model="inShow"> <div class="gn-PubSelect-main" :style="{'he

  • Vue使用v-model封装el-pagination组件的全过程

    使用v-model绑定分页信息对象,分页信息对象包括3个核心属性参数,分页事件直接绑定查询数据的方法,消除父组件的handleSizeChange和handleCurrentChange的绑定事件方法. 1.前言   通过封装el-pagination组件开发自定义分页组件的类似文章网上已经有很多了,但看了一圈,总是不如意,于是决定还是自己动手搞一个. 2.背景 2.1.常规分页处理方法   利用el-pagination组件的常规做法如下:   模板部分: <el-pagination @si

  • vue项目中封装echarts的优雅方式分享

    目录 场景 需求 代码总览 实现 components--chart--index.vue components--chart--index.js components--chart--options main.js chartTest index.vue index.js 代码 总结 补充 补充2:图表高亮轮询,dispatchAction使用 使用方法 附:echarts 饼图调用高亮示例 dispatchAction 补充3:封装echarts地图,姐妹篇 总结 场景 1.Echarts使

  • vue实现列表垂直无缝滚动

    本文实例为大家分享了vue实现列表垂直无缝滚动的具体代码,供大家参考,具体内容如下 实现新闻列表的轮播(如下图) 上代码 封装的so-marquee.vue <template>     <div         class="marquee-wrapper"         :style="{ width: realWidth + 'px' }"     >         <div             class="m

  • vue实现列表的添加点击

    本文实例为大家分享了vue实现列表的添加点击,供大家参考,具体内容如下 使用指令:v-on v-for v-on v-bind v-model html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue.js</title> <style> body {font-family: &quo

  • vue 2.0封装model组件的方法

    本文介绍了vue 2.0封装model组件的方法,分享给大家,希望对大家有所帮助 单文件组件 使用单文件组件封装model的模板.逻辑和样式,之后就可以在页面中调用此通用组件. 需求 model有两个使用场景: 1.备注/修改密码(简易): 在屏幕中垂直居中 2.添加/修改/展示信息(复杂): 距离屏幕顶部200px,内容过长时可滚动. 3.常规要求(共同点): 标题,关闭icon 点击确定/关闭/遮罩,隐藏model组件 分析上述需求点,得到如下图: wrapper:负责遮盖屏幕 inner:

随机推荐