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

滚动条

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

问题描述

当咱们在开发 web app 的时候,常常会遇到一个问题,就是当从一个可滚动的列表页进入到下一个详情页面,而后返回列表页面的时候,很难去还原滚动条的状态,没法记住进来时候的位置。vue

之前我尝试过不少方法:git

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

以上解决方案都不理想github

解决方案

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

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

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

最终就是 vue—page-stack + bs 能够完美实现页面栈的还原后端

下拉加载

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

问题描述

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

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

解决方案

也想了不少的方法,包括计算新增长消息的总长度,而后滚回来,可是消息的类型和高度不一致,计算会有偏差。ui

最终想到的处理办法就是:

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

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

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

现已部署上线,欢迎体验客户端管理端

相关文章
相关标签/搜索