vue中前进刷新、后退缓存用户浏览数据和浏览位置的实例讲解


Posted in Javascript onSeptember 21, 2018

vue中,我们所要实现的一个场景就是:

1.搜索页面==>到搜索结果页时,搜索结果页面要重新获取数据,

2.搜索结果页面==>点击进入详情页==>从详情页返回列表页时,要保存上次已经加载的数据和自动还原上次的浏览位置。

最近在项目中遇到这个问题,思考了几套方案,总是不太完善。百度搜到的方案也基本都只能满足一些很简单的需求。对于复杂一些的情况,还是有些不完善的地方。以下是个人对于这种场景的一个摸索,也参考了百度。如有更好的方案,欢迎指出。

缓存组件,vue2中提供了keep-alive。首先在我们的app.vue中定义keep-alive:

<keep-alive>  
 <router-view v-if="$route.meta.keepAlive"/> 
</keep-alive> 
<router-view v-if="!$route.meta.keepAlive"/>

这里是根据路由中的meta源信息中的keepAlive字段来判断当前路由组件是否需要缓存。这里的meta的keepAlive是我们自定义的,当然你也可以叫别的名字。

下面在router/index.js即我们的路由文件中,定义meta信息:

// list是我们的搜索结果页面
{  
 path: '/list', 
 name: 'List',  
 component: resolve => require(['@/pages/list'], resolve), 
 meta: {  
  isUseCache: false, // 这个字段的意思稍后再说  
  keepAlive: true // 通过此字段判断是否需要缓存当前组件 
 } 
},

上面的component: resolve => require(['@/pages/list'], resolve)这里的组件引入方式可能和大家平时写的有些不一样,这里是为了路由的懒加载用的,大家可以忽略。按照正常的import引入也可以,这个和本次的主题无关。如此一来,vue的路由会帮我们去缓存list页面。

刷新数据or缓存数据的实现:

说这之前,先简单说一下和缓存相关的vue钩子函数。

设置了keepAlive缓存的组件:

第一次进入:beforeRouterEnter ->created->…->activated->…->deactivated

后续进入时:beforeRouterEnter ->activated->deactivated

可以看出,只有第一次进入该组件时,才会走created钩子,而需要缓存的组件中activated是每次都会走的钩子函数。所以,我们要在这个钩子里面去判断,当前组件是需要使用缓存的数据还是重新刷新获取数据。思路有了,下面我们来实现:

// list组价的activated钩子
 activated() {
 // isUseCache为false时才重新刷新获取数据
 // 因为对list使用keep-alive来缓存组件,所以默认是会使用缓存数据的   
 if(!this.$route.meta.isUseCache){   
  this.list = []; // 清空原有数据
  this.onLoad(); // 这是我们获取数据的函数
 } 
},

这里的isUseCache 其实就是我们用来判断是否需要使用缓存数据的字段,我们在list的路由的meta中已经默认设置为false,所以第一次进入list时是获取数据的。

当我们从详情页返回时,我们把list页面路由的isUseCache设置成true,这样我们在返回list页面时会使用缓存数据:

// 详情页面的beforeRouteLeave钩子函数
beforeRouteLeave (to, from, next) {  
 if (to.name == 'List') {
  to.meta.isUseCache = true; 
 }  
 next();
},

我们这里是在即将离开detail页面前判断是否返回的列表页。如果是返回list页面,则把list页面路由的isUseCache字段设置成true。为什么这样设置呢?因为我们对list组件使用的keep-alive进行缓存组件,其默认就是使用缓存的。而我们又在list组件的actived钩子函数中进行了判断:只有在list页面的isUseCache==false时才会清空原有数据并重新获取数据。所以此处设置isUseCache为true,此时返会list页面是不会重新获取数据的,而是使用的缓存数据。

detail返回list可以缓存数据了,那么search前往list页面时怎么让list页面不使用缓存数据而是获取新数据呢?我们重新回到list的activated钩子中:

// list组价的activated钩子
 activated() {
 // isUseCache为false时才重新刷新获取数据
 // 因为对list使用keep-alive来缓存组件,所以默认是会使用缓存数据的   
 if(!this.$route.meta.isUseCache){   
  this.list = []; // 清空原有数据
  this.onLoad(); // 这是我们获取数据的函数
  this.$route.meta.isUseCache = false; } 
},

我们加了一行this.$route.meta.isUseCache=false;也就是从detail返回list后,将list的isUseCache字段为false,而从detail返回list前,我们设置了list的isUseCache为true。所以,只有从detail返回list才使用缓存数据,而其他页面进入list是重新刷新数据的。

至此,一个前进刷新、后退返回的功能基本完成了。

如果场景再复杂一丢丢,比如,如果这个详情页是个订单详情,那么在订单详情页可能会有删除订单的操作。那么删除订单操作后会返回订单列表页,是需要列表页重新刷新的。那么我们需要此时在订单详情页进行是否要刷新的判断。简单改造一下详情页:

data () { 
 return {
  isDel: false // 是否进行了删除订单的操作  
 }
},
beforeRouteLeave (to, from, next) {  
 if (to.name == 'List') {
  // 根据是否删除了订单的状态,进行判断list是否需要使用缓存数据
  to.meta.isUseCache = !this.isDel;    
 }  
 next(); 
},
methods: {  
 deleteOrder () {  
  // 这里是一些删除订单的操作
 
  // 将状态变为已删除订单
  // 所以beforeRouteLeave钩子中就会将list组件路由的isUseCache设置为false 
  // 所以此时再返回list时,list是会重新刷新数据的 
  this.isDel = true; 
  this.$router.go(-1)
 }
}

至此,算是解决了我的vue项目中的这个前进刷新、后退缓存数据和浏览位置的问题。

最后再提一下,页面滚动位置的问题。

问题1:我们知道,在vue这种单页应用中,如果你在a页面滚动了一段距离后,此时前往b页面后,b页面也会停留在a页面的滚动位置。这个问题的解决,我们可以利用router本身提供的功能来解决:

routes: [ 
 {  
  path: '/detail',  
  name: 'Detail',  
  component: resolve => require(['@/pages/detail'], resolve) 
 } 
],
scrollBehavior (to, from, savedPosition) {
 if (savedPosition) {  
   return savedPosition 
 } else {  
   if (from.meta.keepAlive) {  
    from.meta.savedPosition = document.body.scrollTop;  
   }  
   return { x: 0, y: to.meta.savedPosition || 0 } 
 } 
}

scrollBehavior是路由提供的基础功能,这段函数写的是:

1.如果通过浏览器自带的前进后退按钮切换的路由,那么会自动使用浏览默认的回滚上次页面的浏览位置。

2.如果是通过vue路由进行的页面切换。例如a前往b,首先判断a是不是通过keep-alive缓存的组件,如果是,则在a路由的meta中添加一个savedPosition字段,并且值为a的滚动位置。最后return的是页面需要回滚的位置。如此一来,如果打开一个页面,该页面的组件路由中meta.savedPosition为undefined的话,则页面滚动到(0,0)的位置,这样解决了问题1。那么如果打开一个页面,它的路由的meta.savedPosition有值的话,则滚动到上次浏览的位置,因为meta.savedPosition保存的就是上次浏览的位置。

以上这篇vue中前进刷新、后退缓存用户浏览数据和浏览位置的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 中的 &amp;&amp; 和 || 使用小结
Apr 25 Javascript
jquery.post用法之type设置问题
Feb 24 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
Apr 08 Javascript
使用ajaxfileupload.js实现上传文件功能
Aug 13 Javascript
卸载安装Node.js与npm过程详解
Aug 15 Javascript
Angular2数据绑定详解
Apr 18 Javascript
基于vue开发的在线付费课程应用过程
Jan 25 Javascript
详解Axios 如何取消已发送的请求
Oct 20 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
Mar 20 Javascript
详解微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”的解决方案
Apr 04 Javascript
Vue 幸运大转盘实现思路详解
May 06 Javascript
原生js实现html手机端城市列表索引选择城市
Jun 24 Javascript
vue单页面应用打开新窗口显示跳转页面的实例
Sep 21 #Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
Sep 21 #Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 #Javascript
详解Vue中数组和对象更改后视图不刷新的问题
Sep 21 #Javascript
详解vue 数组和对象渲染问题
Sep 21 #Javascript
vue 2.8.2版本配置刚进入时候的默认页面方法
Sep 21 #Javascript
Puppeteer环境搭建的详细步骤
Sep 21 #Javascript
You might like
php 随机生成10位字符代码
2009/03/26 PHP
Wordpress php 分页代码
2009/10/21 PHP
php一行代码获取文件后缀名实例分析
2014/11/12 PHP
php通过记录IP来防止表单重复提交方法分析
2014/12/16 PHP
PHP生成随机数的方法实例分析
2015/01/22 PHP
Yii数据库缓存实例分析
2016/03/29 PHP
TP5(thinkPHP5框架)基于bootstrap实现的单图上传插件用法示例
2019/05/29 PHP
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
2007/04/12 Javascript
用js实现随机返回数组的一个元素
2007/08/13 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
js 为label标签和div标签赋值的方法
2013/08/08 Javascript
JS验证身份证有效性示例
2013/10/11 Javascript
微信小程序 富文本转文本实例详解
2016/10/24 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
vue中简单弹框dialog的实现方法
2018/02/26 Javascript
jQuery实现获取动态添加的标签对象示例
2018/06/28 jQuery
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
Vue.js自定义指令学习使用详解
2019/10/19 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
2020/05/31 Javascript
[45:40]Ti4 冒泡赛第二天NEWBEE vs NaVi 1
2014/07/15 DOTA
Python splitlines使用技巧
2008/09/06 Python
Python利用BeautifulSoup解析Html的方法示例
2017/07/30 Python
详解python中的 is 操作符
2017/12/26 Python
python判断输入日期为第几天的实例
2018/11/13 Python
使用Python和Prometheus跟踪天气的使用方法
2019/05/06 Python
python儿童学游戏编程知识点总结
2019/06/03 Python
Python threading.local代码实例及原理解析
2020/03/16 Python
ipython jupyter notebook中显示图像和数学公式实例
2020/04/15 Python
幼儿园中班教学反思
2014/02/10 职场文书
预防传染病方案
2014/06/14 职场文书
租车协议书
2015/01/27 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
校园安全主题班会
2015/08/12 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
小学思品教学反思
2016/02/20 职场文书
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android