vue 长列表数据刷新的实现及思考

目录
  • 开篇
    • 一、效果展示
    • 二、代码

开篇

通过 vue 进行列表展示的时候如果数据太多可能会卡顿,这里通过滑动计算只创建跟刷新可见部分 dom 元素,这里仅仅代表着复用思路

一、效果展示

两列均为局部可视范围内数据刷新

二、代码

实现的主要思路:

1、提前保留可视div的高度,计算出可视高度能填满情况下最少的单元格条数;

2、根据提供的每个单元格高度和总数据条数计算出总的可滑动div高度,使其可以滑动;

3、在上述可滑动div内部再包裹一层div,此节点的作用就是在滑动过程中,改变自身的 top 值,使之在父节点滑动中始终出现在父节点的可视区域内。

4、根据滑动的距离更新vue数据,但是也只是更新能填满可视区域最小条数。

<div class="main">
    <div v-for="(dom) in longListEl" :key="dom.id" class="longList">
        <div :id="dom.id" class="contain">
            <div style="width: calc(100% - 20px);position: relative;">
                <div :style="{height:`${expectationCellHeight}px`}" v-for="(item,index) in dom.data" :key="item.id">
                    {{ item.title }}
                </div>
            </div>
        </div>
    </div>
</div>
export default {
    data() {
        return {
            longListData:[],
            expectationCellHeight:40,
            longListEl:[{id:'contain',data:[]},{id:'contain1',data:[]}],
            longListDataManages:[]
        };
    },
    mounted() {
        for(let index = 0;index < 250000;index ++){
            this.longListData.push({id:index,title:('我是第' + index + '个')})
        }
        this.$nextTick(()=>{
            this.longListEl.forEach((dom)=>{
                let containEl = document.getElementById(dom.id)
                if(containEl){
                    this.longListDataManages.push(new LongListDataManage(containEl,this.longListData,this.expectationCellHeight,(data)=>{
                        dom.data = data
                    }))
                }
            })
        })
    },
    methods: {
    },
};
function LongListDataManage(el,totalData,expectationCellHeight,refreshDataCallBack){
    this.el = el//需要操作的dom
    this.startIndex = 0//数据源的开始索引
    this.endIndex = 0//数据源的结束索引
    this.containElHeight = el ? el.offsetHeight : 0//可视区域高度
    this.totalData = totalData//全部数据源
    this.refreshDataCallBack = refreshDataCallBack//数据刷新回调
    this.expectationCellHeight = expectationCellHeight//预期的单元cell高度
    this.expectationCellFullScreenNum = 0//预期可视区域展示的单元条数
    this.expectationTotalHeight = 0//预期滑动的最大高度
    this.scrollTop = 0//当前滚动距离
    this.beginRefreshDataDistance = expectationCellHeight//滑动触发刷新数据最小距离,这里仅为一个单元格高度
    // 开始填充数据
    this.begin = function(){
        this.initData()
        this.getCurrentShowDatas()
        this.addListenerScroll()
    }
    // 初始化参数
    this.initData = function(){
        //总高度设定
        this.expectationTotalHeight = this.totalData.length * this.expectationCellHeight
        this.el.style.height = this.expectationTotalHeight + 'px'
        //数据源的结束索引设定(向上取整)
        this.endIndex = this.expectationCellFullScreenNum = Math.ceil((this.containElHeight / this.expectationCellHeight) + 0.1)
    }
    // 开始获取当前需要展示的区间
    this.getCurrentShowDatas = function(){
        //截取数据源开始跟结束节点之间的数据
        let currentData = this.totalData.slice(this.startIndex,this.endIndex)
        //给vue提供数据
        this.refreshDataCallBack(currentData)
    }
    // 监听滚动
    this.addListenerScroll = function(){
        //父节点
        let parentNode = this.el.parentNode
        //第一个子节点(改变其top值实现始终在父节点的可视区域内)
        let firstChild = this.el.firstChild
        let scrollingEvent = ()=>{
            let scrollTop = parentNode.scrollTop
            //滑动的距离超过规定的阀值或者滑动距离为0进行数据源重置
            if(Math.abs(scrollTop - this.scrollTop) >= this.beginRefreshDataDistance || scrollTop <= 0){
                //更改数据源区间索引
                this.startIndex = Math.ceil(scrollTop / this.expectationCellHeight)
                this.endIndex = this.startIndex + this.expectationCellFullScreenNum
                //上下平移可视区域展示dom,实现屏幕相对位置不变
                firstChild.style.top = scrollTop + 'px'
                //回传数据源
                this.getCurrentShowDatas()
                this.scrollTop = scrollTop
            }
        }
        //开始监听滚动
        parentNode.addEventListener("scroll", scrollingEvent)
    }
}

复用其实是由vue来处理的,这里仅是将刷新数据进行了筛选以达到刷新最小数据条数的目的,这里仅仅是简单的实现思路,希望对大家有帮助,更多关于vue 长列表数据刷新的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot vue项目后端列表接口分页模糊查询

    目录 基于 springboot+vue 的测试平台开发 一.分页插件 二.实现接口 1. 编写 Service 层 2. 编写 Controller 层 三.测试接口 1. 测试分页 2. 测试条件查询 基于 springboot+vue 的测试平台开发 继续更新 打开项目管理,就需要看到列表里展示项目数据,比如这样(截图是这个前端框架的demo,仅作示意): 那么对应到我们平台的项目管理功能,就需要有: 列表展示添加的项目数据 可以通过项目名称查询指定的项目 新增项目 编辑项目 其他功能..

  • 结合康熙选秀讲解vue虚拟列表实现

    目录 场景 康熙选妃 多数据渲染 虚拟列表的概念 实现 基本实现 场景 康熙选妃 话说这年是康熙五十三年,天下太平,天下无人不感叹这“康熙盛世”啊,康熙自己也是开心的不得了啊,“朕奋斗了大半辈子,还不能享乐享乐,传命张廷玉来见我,我有事要让他办!” 康熙:衡臣啊(衡臣是张廷玉的字),这康熙盛世如何 张廷玉:皇上牛逼,皇上牛逼,皇上万岁 康熙:但是朕老了啊,但是朕不能服老,朕要证明给天下人看 张廷玉:皇上正值壮年,万岁万万岁 康熙:我不管,我要选妃,我要选妃,我要选妃!!! 张廷玉:我tm...你

  • vue实现列表展示示例详解

    目录 Vue 的CSS之deep语法 ::v-deep classPrefix 前缀 给元素绑定class 总结 Object.freeze 关于Vue和ts的配合问题 ISO8601和dayjs库 一. ISO8601 1. Date对象=>ISO字符串 2. ISO字符串=>Date对象 JS操作时间的库-dayjs 安装 使用 JSON.parse的返回值没有类型 Vue 的CSS之deep语法 ::v-deep 我们知道,在Vue组件的style标签里,加上scoped属性,会使写的样

  • Vue3之列表动画和状态动画示例详解

    目录 概述 示例解析 列表动画 状态动画 总结 概述 列表动画和状态动画都是增加用户体验的方法,当一个列表添加数据或者移除数据时,如果直接添加,突然显示,未免有些突兀,而且用户可能会不知道此时已经有数据加入了,从列表中移除数据也是,用户很有可能不知道当前已经移除了哪一条数据.但是如果加上动画就会好很多了,有趣的动画可以吸引用户的注意力,让用户关注新增和移除的数据.这就是列表动画,而状态动画是指从一个状态到另一个状态的变化,如果直接变过去,就会显得比较生硬,但是如果是加了动画慢慢过渡过去会好很多.

  • 如何让vue长列表快速加载

    vue-long-list-load,满足特殊条件的长列表加载.支持:1.各个节点高度不同且可自由设定 2.各个节点可修改不影响加载效果 3.可精确的滚动到指定位置. 背景 有个长列表渲染的需求,本来用vue-virtual-scroll-list的.但是每个节点的高度不一样,用着有点问题.如果也有相应的需求可以参考下我的方案.欢迎大家交流! vue-long-list-load 满足特殊条件的的长列表加载. 列表内各个节点高度不一,各个节点可以进行修改,定位到指定位置指定节点. www.npm

  • vue长列表优化之虚拟列表实现过程详解

    目录 前言 实现原理 实现代码 总结 前言 应用场景:后台一次性发送上千条或更多数据给前台 场景模拟:用户发起一个请求,后台发送了10w条数据 使用虚拟列表之前:前台需要生成10w个dom节点用来渲染页面 使用虚拟列表之后:前台只需要生成少量dom节点(dom节点数量取决于前端视图需要展示的数量),就可以实现对这10w条数据的视图渲染 总之:虚拟列表就是固定dom节点数量,通过修改dom节点的内容而达到不重新增加(或删除)dom节点来实现列表的更新 实现原理 监听页面滚动,获取滚动的高度scro

  • vue实现前台列表数据过滤搜索、分页效果

    本文实例为大家分享了vue实现列表数据过滤搜索.分页效果的具体代码,供大家参考,具体内容如下 job.vue页面 <style lang="scss"> .job-wrapper { padding-top: 50px; } .job-left { float: left; margin-right: 20px; padding: 20px; width: 310px; background: #fff; } .job-serach-title { margin: 8px

  • vue.js基于v-for实现批量渲染 Json数组对象列表数据示例

    本文实例讲述了vue.js基于v-for实现批量渲染 Json数组对象列表数据.分享给大家供大家参考,具体如下: Vuejs的出现减轻了对DOM的直接操作,同时它提供的 v-for 渲染列表数据也给我们提供了很大的方便.即使是复杂的 Json数组对象,也可以使用 多层嵌套的 v-for 实现,格式如下: <div v-for="(item,index) in items"> <div v-for="(list,index) in item.lists&quo

  • antd-mobile ListView长列表的数据更新遇到的坑

    遇到的问题 listView这个组件我真的是看文档看得脑壳疼.好不容易看文档写完长列表数据展示了.然后遇到一个需求,即用户有一个点赞操作,问题出现了,点赞完数据更新之后listView不刷新列表. 解决列表不刷新问题 官方的demo里有这么一个函数 rowHasChanged ,这个函数返回true或者false,如果是true,则认为这行数据改变了,然后刷新这行数据,也就更新了列表. // 官方 constructor(props) { super(props); ... const data

  • 使用react-virtualized实现图片动态高度长列表的问题

    虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术.虚拟列表是对长列表场景一种常见的优化,毕竟很少有人在列表中渲染上百个子元素,只需要在滚动条横向或纵向滚动时将可视区域内的元素渲染出即可. 开发中遇到的问题 1.长列表中的图片要保持原图片相同的比例,那纵向滚动在宽度不变的情况下,每张图片的高度就是动态的,当该列表项高度发生了变化,会影响该列表项及其之后所有列表项的位置信息. 2.图片width,height必须在图片加载完成后才能获得. 解决方案 我们使用react-

  • vue主动刷新页面及列表数据删除后的刷新实例

    1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求. 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.reload(),或者router.go(0)刷新时,整个浏览器进行了重新加载,闪烁,体验不好 3.解决方法 provide / inject 组合 作用:允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效. App.vue: 声明reload方法,控制

  • vue列表数据删除后主动刷新页面及刷新方法详解

    问题描述: 前端删除一条数据或者新增数据后,后端操作成功,但前端不会自动刷新,需要重新刷新当前页面 (用vue-router重新路由到当前页面,页面是不进行刷新的 ,采用window.reload(),或者router.go(0)刷新时,整个浏览器进行了重新加载) 解决: provide / inject 组合 作用:允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效. (声明reload方法,控制router-view的显示或隐藏,从而控制页

  • Vue+WebSocket页面实时刷新长连接的实现

    最近vue项目要做数据实时刷新,折线图每秒重画一次,数据每0.5秒刷新一次,说白了就是实时刷新,因为数据量较大,用定时器估计页面停留一会就会卡死... 与后台人员讨论过后决定使用h5新增的WebSocket来实现数据实时展示,记录一下过程以及碰到的问题: 注意:页面刷新长连接会被关闭,其实进入当前页面建立长连接的目的就是页面不用F5刷新,所有数据自动实时刷新,如果还是来回F5大刷页面那就没有意义了... ps: 如果实在有这个需求的话,网上貌似有实现刷新页面长连接不断的方法,请自行百度....

随机推荐