• Vue单页面,多路由、前进刷新、后退不刷新


    • 利用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;
           
             },
  • 相关阅读:
    << 和>> 的计算公式
    死锁面试题(什么是死锁,产生死锁的原因及必要条件)
    SpringBoot的注解:@SpringBootApplication注解 vs @EnableAutoConfiguration+@ComponentScan+@Configuration
    SpringBoot入门-15(springboot配置freemarker使用YML)
    shiro 登录
    springMVC RedirectAttributes
    IDEA3.5最新版激活码
    求递归算法时间复杂度:递归树
    渐进复杂度
    PL/SQL注册码
  • 原文地址:https://www.cnblogs.com/caoxiangwang/p/12660938.html
Copyright © 2020-2023  润新知