Vue记住滚动条和实现下拉加载的完美方法


Posted in Javascript onJuly 31, 2020

滚动条

常见于移动端 App 在滚动点击进入的时候

问题描述

当我们在开发 web app 的时候,经常会遇到一个问题,就是当从一个可滚动的列表页进入到下一个详情页面,然后返回列表页面的时候,很难去还原滚动条的状态,无法记住进来时候的位置。
以前我尝试过很多方法:

  1. 有 vue-router 自带的 scrollBehavior,需要记住 scrollTop,然后还原,但是管理这个 scrollTop 显得很麻烦,有的时候还不容易取值还有使用纯 CSS 的方式,在列表页面放置一个 router-view,详情页面利用 position 和 z-index 覆盖列表页面,返回后直接显示的就是原来的列表页面,这个必须把各层页面路由预先配置好,不然就会显示混乱了,并且同一个页面出现在不同的子路由下,需要配置多次,比如商品详情需要配置在很多个地方,造成冗余
  2. 以上解决方案都不理想

解决方案

后来我参考 keep-alive 开发了 vue-page-stack 来保存 Vue 页面的栈,即 Vue 中的虚拟 dom,但是滚动条的问题仍然没解决。因为虚拟 dom 没有记录各个组件的滚动状态,所以无法恢复。

在我使用 cube-ui 的时候发现,使用这个组件库里面的滚动容器,是可以还原出滚动条的,进一步发现是黄轶老师的 better-scroll 的原因。

通过查看 bs 的源码发现,原来是 bs 的内部实现不是原生滚动,而是记录一些滚动的信息,其中最重要的就是 x 和 y,也就是滚动的值,自己实现了一套滚动行为通过 transform 去实现,在还原虚拟 dom 的时候,滚动的信息也被还原了。

最终就是 vue-page-stack + bs 可以完美实现页面栈的还原

下拉加载

这个问题多见于消息记录等查询,在小程序中也会这遇到这样的问题

问题描述

绝大多数滚动场景都是上拉加载,上拉加载的时候,加载的内容在滚动区域的下方出现,加载之后,我们将数据添加到列表,由 Vue 等负责渲染新加载的内容,我们继续上拉就可以继续滚动查看。

但在我们的场景下,在某一会话中翻阅消息记录的时候,是下拉加载更多消息,加载后,继续下拉慢慢滚动查看。这就导致了一个很严重的问题:下拉加载后出现的内容在滚动区域的上方,不做任何处理的话加载后会直接跳到新加载内容的最上方,因为滚动距离没变,这就出问题了,和我们想实现的不一致。

解决方案

也想了很多的方法,包括计算新增加消息的总长度,然后滚回来,但是消息的类型和高度不一致,计算会有误差。
最终想到的处理办法就是:

  1. 通过接口获取到加载信息后首先标记(使用 shouldScroll 标记)后端返回的第一条信息,也就是加载后我们的视角要看到的新内容
  2. messageList 更新后,Vue 会更新数据和视图,这时候页面 dom 被更新了
  3. MessageItem 组件 mounted 后,这时候已经完成了视图的渲染,通过检查标记(shouldScroll),通知父容器滚动到刚才标记的位置,也就是加载的第一条信息处,这样也就把渲染和滚动做到一起了

以上两个问题在下图均有体现,效果还可以,如下:

Vue记住滚动条和实现下拉加载的完美方法

以上内容在我的即时通讯应用客户端中均有体现,欢迎查看源码

总结

到此这篇关于Vue记住滚动条和实现下拉加载的完美方法的文章就介绍到这了,更多相关Vue滚动条和下拉加载内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
利用javascript中的call实现继承
Jan 22 Javascript
ExtJS[Desktop]实现图标换行示例代码
Nov 17 Javascript
JS简单实现动画弹出层效果
May 05 Javascript
AngularJS入门教程之Scope(作用域)
Jul 27 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
Sep 16 Javascript
jQuery遮罩层实例讲解
May 11 jQuery
Angular2使用Angular CLI快速搭建工程(一)
May 21 Javascript
vue中如何实现变量和字符串拼接
Jun 19 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
Mar 08 Javascript
vue-cli 目录结构详细讲解总结
Jan 15 Javascript
vue实现跳转接口push 转场动画示例
Nov 01 Javascript
微信小程序加载机制及运行机制图解
Nov 27 Javascript
vue中渲染对象中属性时显示未定义的解决
Jul 31 #Javascript
JS可断点续传文件上传实现代码解析
Jul 30 #Javascript
Vue单文件组件开发实现过程详解
Jul 30 #Javascript
vue实现从外部修改组件内部的变量的值
Jul 30 #Javascript
在vue中实现嵌套页面(iframe)
Jul 30 #Javascript
Vue文本模糊匹配功能如何实现
Jul 30 #Javascript
VUE 单页面使用 echart 窗口变化时的用法
Jul 30 #Javascript
You might like
世界咖啡生产者论坛呼吁:需要立即就咖啡价格采取认真行动
2021/03/06 咖啡文化
php 团购折扣计算公式
2011/11/24 PHP
Thinkphp使用mongodb数据库实现多条件查询方法
2014/06/26 PHP
基于递归实现的php树形菜单代码
2014/11/19 PHP
PHP的PDO常用类库实例分析
2016/04/07 PHP
PHP中FTP相关函数小结
2016/07/15 PHP
Laravel框架实现抢红包功能示例
2019/10/31 PHP
Laravel框架数据库迁移操作实例详解
2020/04/06 PHP
网页中的图片的处理方法与代码
2009/11/26 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
2013/03/17 Javascript
JS弹出对话框实现方法(三种方式)
2015/12/18 Javascript
angular route中使用resolve在uglify压缩后问题解决
2016/09/21 Javascript
React创建组件的三种方式及其区别
2017/01/12 Javascript
JS数组去重(4种方法)
2017/03/27 Javascript
深入探究angular2 UI组件之primeNG用法
2017/07/26 Javascript
用js实现before和after伪类的样式修改的示例代码
2017/09/07 Javascript
浅谈Angular 中何时取消订阅
2017/11/22 Javascript
详解vue 数据传递的方法
2018/04/19 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
[11:01]2014DOTA2西雅图邀请赛 冷冷带你探秘威斯汀
2014/07/08 DOTA
[04:29]2016国际邀请赛中国区预选赛Ehome战队教练采访
2016/06/27 DOTA
[01:10:03]OG vs EG 2018国际邀请赛淘汰赛BO3 第三场 8.23
2018/08/24 DOTA
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
pytorch 共享参数的示例
2019/08/17 Python
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
腾讯技术类校园招聘笔试试题
2014/05/06 面试题
介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)
2014/10/31 面试题
毕业生在校学习的自我评价分享
2013/10/08 职场文书
函授本科毕业生自我鉴定
2013/10/16 职场文书
八一演出活动方案
2014/02/03 职场文书
元旦晚会活动总结
2014/07/09 职场文书
护士个人总结范文
2015/02/13 职场文书
生产车间管理制度
2015/08/04 职场文书