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 相关文章推荐
jquery将一个表单序列化为一个对象的方法
Jan 03 Javascript
JavaScript中的toDateString()方法使用详解
Jun 12 Javascript
jquery实现根据浏览器窗口大小自动缩放图片的方法
Jul 17 Javascript
jquery.validate提示错误信息位置方法
Jan 22 Javascript
javascript实现dom元素可拖动
Mar 21 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
Oct 10 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
Dec 23 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
Aug 31 Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 Javascript
微信小程序时间戳转日期的详解
Apr 30 Javascript
vue 源码解析之虚拟Dom-render
Aug 26 Javascript
node crawler如何添加promise支持
Feb 01 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
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
PHP中“=>
2019/03/01 PHP
基于laravel缓冲cache的用法详解
2019/10/23 PHP
犀利的js 函数集合
2009/06/11 Javascript
js 编程笔记 无名函数
2011/06/28 Javascript
javasctipt如何显示几分钟前、几天前等
2014/04/30 Javascript
百度UEditor编辑器如何关闭抓取远程图片功能
2015/03/03 Javascript
JavaScript创建闭包的两种方式的优劣与区别分析
2015/06/22 Javascript
js和jQuery设置Opacity半透明 兼容IE6
2016/05/24 Javascript
JS实现的打字机效果完整实例
2016/06/20 Javascript
Angularjs 自定义服务的三种方式(推荐)
2016/08/02 Javascript
javascript特殊文本输入框网页特效
2016/09/13 Javascript
vuex如何重置所有state(可定制)
2019/01/17 Javascript
开源一个微信小程序仪表盘组件过程解析
2019/07/30 Javascript
学习 Vue.js 遇到的那些坑
2021/02/02 Vue.js
python使用分治法实现求解最大值的方法
2015/05/12 Python
Python抓取淘宝下拉框关键词的方法
2015/07/08 Python
python 实现在txt指定行追加文本的方法
2018/04/29 Python
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
2018/06/13 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
Python实现将多个空格换为一个空格.md的方法
2018/12/20 Python
利用python实现周期财务统计可视化
2019/08/25 Python
使用python实现数组、链表、队列、栈的方法
2019/12/20 Python
python selenium自动化测试框架搭建的方法步骤
2020/06/14 Python
Python+Kepler.gl轻松制作酷炫路径动画的实现示例
2020/06/02 Python
用OpenCV进行年龄和性别检测的实现示例
2021/01/29 Python
北京某科技有限公司C# .net笔试题
2014/09/27 面试题
汽车检测与维修个人求职信
2013/09/24 职场文书
应届大专生自荐书
2014/06/16 职场文书
改革共识倡议书
2014/08/29 职场文书
幼儿园六一主持词
2015/06/30 职场文书
选择比努力更重要?这是长期以来对“努力”的最大误解
2019/07/12 职场文书
nginx限制并发连接请求数的方法
2021/04/01 Servers
SQL Server Agent 服务无法启动
2022/04/20 SQL Server
zabbix 代理服务器的部署与 zabbix-snmp 监控问题
2022/07/15 Servers