zoukankan      html  css  js  c++  java
  • vue 后退不刷新,前进刷新 keep-alive

    最近在开发中遇到了这样的一个问题:

    A、B、C三个页面,有如下这样的场景:

    (1)从页面A离开进入B或C的时候,缓存A页面的数据,并且返回到A后,能保持A页面的跳转前职位

    (2)离开B进入C的时候,缓存B

    (3)离开B进入A的时候,不缓存

    现在开始分步解决:

    方案一:

    从场景中可是看出A、B是需要缓存的,

    首先修改app.vue

    <template>
      <div id="app">
        <keep-alive :include="['Index', 'List']">
          <router-view/>
        </keep-alive>
      </div>
    </template>

    include是A、B页面中的name值,注意,include接受的是数组字符串

    然后就是A页面进入B页面的时候刷新,即离开B进入A的时候不缓存,那么就需要用到beforeRouteEnter(),此函数在mounted()执行后执行,不是methods中的自定义函数

    export default {
      name: "List",
      beforeRouteEnter(to, from, next) {
          next(vm => {
            // 通过 `vm` 访问组件实例
            if (from.fullPath == '/' && to.fullPath.indexOf('/list') > -1) { //一定是从A进到B页面才刷新
               vm.initFn(); //initFn是本来写在mounted里面的各种, 执行顺序是:先执行mounted,然后是此处
            }
          })
       },
      methods: {
        initFn() {
          ... //获取数据
        }
      } }

    返回到原来的位置用到的是router中的scrollBehavior():

    router.js:

    new Router({
        routes: [],
        scrollBehavior(to, from, savedPosition) {
          // keep-alive 返回缓存页面后记录浏览位置
          if (savedPosition && to.meta.isKeepAlive) {
            return savedPosition;
          }
          // 异步滚动操作
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve({ x: 0, y: 1 });
            }, 0);
          });
        }
    })
    有时候会有返回不回去的情况,可做延时处理:
    new Router({
        routes: [],
        scrollBehavior(to, from, savedPosition) {
          // keep-alive 返回缓存页面后记录浏览位置
          if (savedPosition && to.meta.isKeepAlive) {
             setTimeout(() => { //延时
               window.scrollTo(savedPosition.x, savedPosition.y)
             }, 10);
          }
          // 异步滚动操作
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve({ x: 0, y: 1 });
            }, 0);
          });
        }
    })

    除了使用keep-alive的include属性,可通过给router中添加mate参数控制

    app.vue:

    <template>
      <div id="app">
        <keep-alive>
          <router-view v-if="$route.meta.isKeepAlive"/>
        </keep-alive>
        <router-view v-if="!$route.meta.isKeepAlive"/>
      </div>
    </template>

    注意此处if判断中的meta后的值要与router中的一致

    router.js

    const router = new Router({
      routes: [
        {
          path: '/',
          name: 'Index',
          component: Index,
          meta: {
            isKeepAlive: true
          }
        },
        {
          path: '/list/:id', 
          name: 'List',
          component: List,
          meta: {
            isKeepAlive: true
          }
        }
      ],
      scrollBehavior(to, from, savedPosition) {
        // keep-alive 返回缓存页面后记录浏览位置
        if (savedPosition && to.meta.isKeepAlive) {
          return savedPosition;
        }
        // 异步滚动操作
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve({ x: 0, y: 1 });
          }, 0);
        });
      }
    });
    export default router;

    当然还有其他的解决方法,如destory()。

    方案二:

    利用$destroy()销毁:

    beforeRouteLeave (to: any, from: any, next: any) {
      // 导航离开该组件的对应路由时调用
      // 判断是否是去往页面 C 
      if (to.name !== 'C') {
        // 不是去 C 页面,不缓存
        this.$destroy()
      }
      next()
    }

    但bug是销毁后将永远不会再次缓存。

    网上还有给出其他方案,查看源码可以发现缓存是通过添加cache属性存储vnode的,如通过源码的cache属性,强制移除某个对象,缺点是没有彻底销毁依旧占内存,不过我没有实验,具体的就不知道了。

    还有就是动态设置router.js中的keepAlive值,通过beforeRouteLeave(to, from, next)中的to,from判断url,动态设置keepAlive是true还是false,但设置为true缓存后,即使再设置为false也不会清除缓存,那么会出现bug,列表页不同id的进入,始终是第一次进入时的数据。

    经过多次测试,发现方案一的两种写法均是可行且没出现bug的,记录下,方便以后复习

  • 相关阅读:
    【R】爬虫案例
    [R] 保存pheatmap图片对象到文件
    [R] 添加误差棒的分组折线图:geom_path: Each group consists of only one observation. Do you need to adjust the...
    [R] read.table/read.delim读入数据行数变少?
    [R] cbind和filter函数的坑
    [R]在dplyr函数的基础上编写函数(3)tidyeval
    [R]在dplyr基础上编写函数(2)substitute和quote
    30个Java知识点
    Java的30个知识点
    40个知识点
  • 原文地址:https://www.cnblogs.com/cyj7/p/10824522.html
Copyright © 2011-2022 走看看