博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue-router中scrollBehavior的妙用
阅读量:6219 次
发布时间:2019-06-21

本文共 2129 字,大约阅读时间需要 7 分钟。

1. keep-alive

  • 问题: 使用keep-alive标签后部分安卓机返回缓存页位置不精确问题

  • 解决方案:

复制代码
const router = new Router({  scrollBehavior(to, from, savedPosition) {    if (savedPosition && to.meta.keepAlive) {      return savedPosition;    }    return { x: 0, y:0 };  },});复制代码

2. 页面返回出现空白屏问题

  • 问题
【前提】:iOS设备【步骤】: 页面A是个列表很长-->滑到页脚的时候点击跳转之后到页面B--->再返回A页面         --->屏幕会出现空白遮罩层--->手指轻触屏幕滑动--->遮罩层消失复制代码

解决方案一

在接口请求成功后的回调操作完成后进行该操作,例如

// fetchCourseList是一个封装好的Promise请求fetchCourseList().then(({ data: courses }) => {  this.courses = courses;}).then(() => {    setTimeout(() => {        window.scrollTo(0, 1);        window.scrollTo(0, 0);    });});复制代码

该方案的弊端: 每个页面都需要做这样的处理,不推荐使用。

解决方案二(推荐)

使用scrollBehavior中的异步滚动操作

const router = new Router({  scrollBehavior(to, from, savedPosition) {    // keep-alive 返回缓存页面后记录浏览位置    if (savedPosition && to.meta.keepAlive) {      return savedPosition;    }    // 异步滚动操作    return new Promise((resolve) => {      setTimeout(() => {        resolve({ x: 0, y: 1 });      }, 0);    });  },});复制代码

该方案直接在路由进行处理,兼容每个页面并且页面加载完后并也不会产生1px的滚动位置。

这里为什么不能直接return而必须使用异步滚动操作呢?以下是个人的一些见解欢迎大家来探讨指正。

  1. 首先我们要先去了解scrollBehavior函数究竟在组件的哪个生命周期后才开始执行。这里我对组件的每个生命周期和scrollBehavior函数进行alert,经排查结果:scrollBehavior函数在组件的生命周期mounted后beforeUpdate前执行。

  2. 在scrollBehavior函数中直接return{ x:0, y:100},进入页面仍在顶部。为什么不会滚动到100px处?猜测:mounted中的异步请求回来的数据赋值给data中的变量a,变量a因为vue的双向绑定更新了view层而引起滚动失效?

  3. 验证下以上的猜测,设置一个静态页面数据都已经在html上写死。scrollBehavior函数中直接return { x:0, y: 100},结果:进入页面都会滚动到100px处。证明:确实与异步请求回来后的操作有关系。

  4. 接着了解vue的mounted和beforeUpdate时期都做了些什么。mounted时期:data数据已经挂在到页面上。beforeUpdate和updated时期:当vue发现data中的数据发生了改变,会触发对应组件的重新渲染。

  5. 根据步骤4.mounted时期发起的异步请求并不会阻碍主线程的后续操作,所以请求回调事件未触发(对data中的变量a赋值操作未执行)便继续去执行scrollBehavior函数。如果此时直接return{ x:0, y:100}。此时相当于在异步请求回调事件未执行前进行了滚动。等到滚动后异步请求回调事件开始执行,对data中的变量a被赋值,引起组件重新渲染又回到了顶部。这整个流程滚动是针对data的初始数据页进行滚动的,所以遮罩层仍会出现。

  6. 综合上述:必须使用异步滚动,利用setTimeout跳出主线程将回调事件放到队列中。由于mouted比scrollBehavior函数早执行,所以异步请求的回调事件优先进入队列,接下去才是setTimeout的回调事件。根据队列 先进先出的原理。先执行了异步请求回调事件对data中的变量a做赋值操作。此时相当于这已经是个静态页面了,接着我只要执行return { x:0, y: 100 }。这样就已经触发了页面滚动到100px的效果。但是由于data数据发生改变,页面重新渲染又回到顶部。这时整个轻触滚动效果已经暗中执行完成,不会再出现遮罩层了。

转载地址:http://rymja.baihongyu.com/

你可能感兴趣的文章
揭开数据库RPO等于0的秘密(下)
查看>>
Android Button
查看>>
“死”法不重样,一根数据线如何从“机器伴侣”变身电脑杀手?
查看>>
CountDownLatch详解
查看>>
云时代重新定义主机安全:自动化安全闭环是核心
查看>>
abap选择屏幕工具栏按钮问题
查看>>
【Java】I/O类库
查看>>
WPF 4 Ribbon 开发 之 标签工具栏(Tab Toolbar)
查看>>
传闻 Android Q 将支持手机应用版本回滚
查看>>
Visual Studio Code 1.33 发布
查看>>
jQuery幻灯片播放器插件
查看>>
并发——读写锁初探
查看>>
BAT研发面试36题总结:Spring+Redis+Docker+Dubbo+高并发架构
查看>>
Android Animation(动画)---基础二(LayoutAnimationController)
查看>>
python docx文档转html页面
查看>>
阿里如何做到在线业务百分百容器化
查看>>
死锁查看处理(三)
查看>>
rabbitmq 启动与停止
查看>>
浅谈unicode编码和utf-8编码的关系
查看>>
LinuxOS
查看>>