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

2019-05-11  本文已影响0人  简爱的三年

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

最近一个项目中遇见这个问题,思来想去,总没有特别好的方案,于是百度查找各种解决办法,最后整理归纳如下解决思路:

列表.png 详情.png

1. 缓存组件,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字段来判断当前路由组件是否需要缓存。这里的metakeepAlive是我们自定义的,当然你也可以叫别的名字。

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


// news 是列表页
{      
    path: '/news ',  
    name: 'news ',      
    component: resolve => require(['@/view/news'], resolve),    
    meta: {        
        keepAlive: true  // 通过此字段判断是否需要缓存当前组件  
    }    
},

这里采用路由懒加载,大家也可以使用 import 来导入,无关紧要,接着看下面

缓存数据的实现

先简单了解一下缓存相关的vue钩子函数。

设置了keepAlive缓存的组件:

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

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


页面滚动位置的问题

  1. 我们知道,在vue这种单页应用中,如果你在a页面滚动了一段距离后,此时前往b页面后,b页面也会停留在a页面的滚动位置。这个问题的解决,我们可以利用router本身提供的功能来解决:
routes: [    
    {      
        path: '/detail',      
        name: 'Detail',      
        component: resolve => require(['@/view/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保存的就是上次浏览的位置。

上一篇 下一篇

猜你喜欢

热点阅读