vue实现前进刷新,后退不刷新

项目中客户提出返回列表页需要缓存之前查询的数据,用到了以下方法解决了这个需求

实现思路:
注:demo中,index页面包含三个链接导航。page1-->page2-->page3.依次前进,每次前进到一个新页面都需要获取数据,而按下后退键后,从page3返回到page2,page2不再获取新数据,而是使用之前缓存的数据。从page2返回到page1时,page1不再获取新数据,而是使用之前的数据。所以,page1和page2需要缓存,page3不需要缓存。可以把page1想象成首页,page2想象成详情页,page3想象成订单提交页。这样方便理解。

利用keep-alive 缓存需要缓存的页面

  • 在app.vue中改写router-view

<keep-alive>
    <router-view v-if="$route.meta.keepAlive">
        <!-- 这里是会被缓存的视图组件,比如 page1,page2 -->
    </router-view>
</keep-alive>
 
<router-view v-if="!$route.meta.keepAlive">
    <!-- 这里是不被缓存的视图组件,比如 page3 -->
</router-view>

在router/index.js中添加路由元信息,设置需要缓存的页面

routes: [{
        path: '/',
        name: 'index',
        component: index,
        meta: {
            keepAlive: false, //此组件不需要被缓存
        }
    },
    {
        path: '/page1',
        name: 'page1',
        component: page1,
        meta: {
            keepAlive: true, //此组件需要被缓存
            
        }
    },
    {
        path: '/page2',
        name: 'page2',
        component: page2,
        meta: {
            keepAlive: true, // 此组件需要被缓存
           
        }
    },
    {
        path: '/page3',
        name: 'page3',
        component: page3,
        meta: {
            keepAlive: false, // 此组件不需要被缓存
        }
    }
]

钩子函数的执行顺序

不使用keep-alive
beforeRouteEnter --> created --> mounted --> destroyed

使用keep-alive
beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次进入缓存的页面,只会触发beforeRouteEnter -->activated --> deactivated 。created和mounted不会再执行。我们可以利用不同的钩子函数,做不同的事。务必理解上述钩子函数的执行时机和执行顺序,本教程的核心就依赖于此钩子函数
activated和deactivated是使用keep-alive后,vue中比较重要的两个钩子函数,建议详细了解下。

需缓存的页面的写法

注:demo中的page1和page2,这两个页面都需要缓存,思路一样,以下以page1为例,page2不再赘述。
示例文件:components/page1.vue

data中初始化一个str字符串,存放从后台获取的数据

     data() {
       return {
         msg: "我是第一个页面",
         str: ""  // 加载页面后执行获取数据的方法,插入到此
       };
     }

methods中创建一个方法,模拟从后台获取数据

     methods: {
       getData() {
         // getData方法,模拟从后台请求数据
         this.str = "我是通过调用方法加载的数据。。。";
       }
     }

修改router/index.js中的配置

每次进入页面,我们都需要知晓是从哪个页面进来的,用以判断是否需要获取数据。以这个page1页面为例,当我们知晓是从page2过来的,我们就可以认为是用户操作了返回键,这时page1页面就不需要再获取新数据了,使用之前缓存的数据就可以了。如果是从别的页面过来的,我们就需要获取数据。

我们可以通过beforeRouteEnter这个钩子函数中的from参数判断是从哪个页面过来的,这个参数执行时,组件实例还没创建,所有不能在data中定义变量。我们可以在路由中定义一个变量,用来判断。

在router/index.js的meta中添加isBack变量,默认false
 

     {
          path: '/page1',
          name: 'page1',
          component: page1,
          meta: {
              keepAlive: true, //此组件需要被缓存
              isBack:false, //用于判断上一个页面是哪个
          }
      },
      {
          path: '/page2',
          name: 'page2',
          component: page2,
          meta: {
              keepAlive: true, // 此组件需要被缓存
              isBack:false, //用于判断上一个页面是哪个
          }
      },

beforeRouteEnter中判断是从哪个页面过来的

  • 判断是从哪个路由过来的,如果是page2过来的,表明当前页面不需要刷新获取新数据,直接用之前缓存的数据即可

        beforeRouteEnter(to, from, next) {
          // 路由导航钩子,此时还不能获取组件实例 `this`,所以无法在data中定义变量(利用vm除外)
          // 参考 https://router.vuejs.org/zh-cn/advanced/navigation-guards.html
          // 所以,利用路由元信息中的meta字段设置变量,方便在各个位置获取。这就是为什么在meta中定义isBack
          // 参考 https://router.vuejs.org/zh-cn/advanced/meta.html
          if(from.name=='page2'){
              to.meta.isBack=true;
              //判断是从哪个路由过来的,
              //如果是page2过来的,表明当前页面不需要刷新获取新数据,直接用之前缓存的数据即可
          }
      
          next();
        },
    

    activated中执行getData这个获取数据的方法

  • 因为这个页面需要缓存。只有第一次进入时才会执行created和mounted方法,再次进入就不执行了。而activated每次进入都执行,所以在这个钩子函数中获取数据。

    activated() {
      if(!this.$route.meta.isBack){
        // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
        this.getData();
      }
      // 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据
      this.$route.meta.isBack=false
     
    },
    

    这样就可以了?

    当这样设置完毕后,你执行起来,貌似是可以了。第一次进入page1,能获取新数据,从page2返回时,不再获取新数据了,而是使用之前缓存的数据。但这样还有一个问题,当用户从page1进入page2后,因为某种原因,手动刷新了page2的页面。这时再返回到page1,发现之前缓存的数据丢失了,而且也没有再重新获取。所以我们还需要再添加一个判断条件,当用户手动刷新页面后,再返回时就需要重新获取数据了。

    如何添加这个条件,判断用户是否刷新了页面呢?我们知道,当使用keep-alive后,只有第一次进入后会触发created钩子函数,再次进入就不再执行了。当用户刷新了页面,这个钩子函数就会又执行,所以,我们可以利用这个小技巧来做点文章。

    data中定义变量isFirstEnter用来判断是否第一次进入,或是否刷新了页面,默认false
     

       data() {
         return {
           msg: "我是第一个页面",
           str: "",  // 加载页面后执行获取数据的方法,插入到此
           isFirstEnter:false // 是否第一次进入,默认false
         };
       },
    

    created中把isFirstEnter变为true,说明是第一次进入或刷新了页面

       created() {
         this.isFirstEnter=true;
         // 只有第一次进入或者刷新页面后才会执行此钩子函数
         // 使用keep-alive后(2+次)进入不会再执行此钩子函数
       },
    

    activated中增加判断条件

       activated() {
         if(!this.$route.meta.isBack || this.isFirstEnter){
             // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
             // 如果isFirstEnter是true,表明是第一次进入此页面或用户刷新了页面,需获取新数据
             this.str=''// 把数据清空,可以稍微避免让用户看到之前缓存的数据
             this.getData();
         }
         // 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据
         this.$route.meta.isBack=false
         // 恢复成默认的false,避免isBack一直是true,导致每次都获取新数据
         this.isFirstEnter=false;
     
       },
    

    原文:https://blog.csdn.net/qq_40963664/article/details/80062130

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue实现后退刷新前进刷新的方法有很多种,其中一种比较常用的方法是使用Vue Router中的导航守卫(Navigation Guards)。 具体实现方法如下: 1. 在Vue Router中定义路由,给需要实现后退刷新前进刷新的路由添加 meta 属性,例如: ``` { path: '/home', name: 'home', component: Home, meta: { keepAlive: true } } ``` 2. 在 Vue 中添加导航守卫,根据 meta 属性的值设置路由的缓存状态。例如: ``` router.beforeEach((to, from, next) => { if (to.meta.keepAlive) { // 如果需要缓存,则将路由设置为缓存状态 to.meta.isKeepAlive = true; } else { // 否则不缓存 to.meta.isKeepAlive = false; } next(); }); router.afterEach((to, from) => { // 根据路由的缓存状态设置页面是否缓存 if (from.meta.isKeepAlive && !to.meta.isKeepAlive) { // 如果从缓存页跳转到非缓存页,则销毁缓存页 from.meta.keepAlive = false; from.meta.isKeepAlive = false; } else if (!from.meta.isKeepAlive && to.meta.isKeepAlive) { // 如果从非缓存页跳转到缓存页,则缓存页不刷新 to.meta.keepAlive = true; to.meta.isKeepAlive = true; } else { // 其他情况下,刷新页面 location.reload(); } }); ``` 通过上述方法,我们可以在 Vue实现后退刷新前进刷新的效果。当从缓存页跳转到非缓存页,缓存页将被销毁,避免了内存泄漏;当从非缓存页跳转到缓存页,缓存页不会刷新,提高了页面的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值