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 相关文章推荐
用jquery实现学校的校历(asp.net+jquery ui 1.72)
Jan 01 Javascript
js下通过getList函数实现分页效果的代码
Sep 17 Javascript
javascript中检测变量的类型的代码
Dec 28 Javascript
jQuery数组处理代码详解(含实例演示)
Feb 03 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
Oct 31 Javascript
input输入密码变黑点密文的实现方法
Jan 09 Javascript
JSON与js对象序列化实例详解
Mar 16 Javascript
使用vue.js写一个tab选项卡效果
Mar 25 Javascript
Vue AST源码解析第一篇
Jul 19 Javascript
vue项目中使用bpmn为节点添加颜色的方法
Apr 30 Javascript
Canvas跟随鼠标炫彩小球的实现
Apr 11 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 adodb分页实现代码
2009/03/19 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
解决php的“It is not safe to rely on the system’s timezone settings”问题
2015/10/08 PHP
PHP实现补齐关闭的HTML标签
2016/03/22 PHP
Laravel SQL语句记录方式(推荐)
2016/05/26 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
PHP使用反向Ajax技术实现在线客服系统详解
2019/07/01 PHP
查询绑定数据岛的表格中的文本并修改显示方式的js代码
2009/12/15 Javascript
jquery实现盒子下拉效果示例代码
2013/09/12 Javascript
jQuery之过滤元素操作小结
2013/11/30 Javascript
自己使用jquery写的一个无缝滚动的插件
2014/04/30 Javascript
jQuery中map()方法用法实例
2015/01/06 Javascript
js判断某个方法是否存在实例代码
2015/01/10 Javascript
高性能JavaScript模板引擎实现原理详解
2015/02/05 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
微信小程序 五星评分(包括半颗星评分)实例代码
2016/12/14 Javascript
Vue.js对象转换实例
2017/06/07 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
2017/11/24 Javascript
vue vuex vue-rouert后台项目——权限路由(适合初学)
2017/12/29 Javascript
JS简单生成由字母数字组合随机字符串示例
2018/05/25 Javascript
详解如何从零开始搭建Express+Vue开发环境
2018/07/17 Javascript
通过实例解析javascript Date对象属性及方法
2020/11/04 Javascript
python 创建弹出式菜单的实现代码
2017/07/11 Python
Python使用configparser库读取配置文件
2020/02/22 Python
python list的index()和find()的实现
2020/11/16 Python
Python环境搭建过程从安装到Hello World
2021/02/05 Python
韩国三星旗下的一家超市连锁店:Home Plus
2016/07/30 全球购物
匡威荷兰官方网站:Converse荷兰
2018/10/24 全球购物
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
亿企通软件测试面试题
2012/04/10 面试题
旅游业大学生创业计划书
2014/01/31 职场文书
《两只鸟蛋》教学反思
2014/02/10 职场文书
党员转正党支部意见
2015/06/02 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript