vue使用keep-alive指令缓存页面和清除缓存

业务背景

手机端,创建视频会议的场景
用户从首页home,点击创建会议,跳转到创建会议页面create,其中选择与会人员需要跳转到另一个联系人的页面contacts,勾选选联系人,选中联系人后,在返回到create页面,原来在create页面录入的数据要保持。

解决思路

  1. 使用keep-alive指令缓存create页面
  2. 使用keep-alive指令 的include属性 指定哪些需要缓存,通过修改include来清楚缓存
  3. 使用vuex来保存 需要缓存的 include值 数组arr
  4. 使用路由守卫,监听离开create页面时的事件beforeRouteLeave,判断如果不是跳转到contancts页面(比如返回首页,那么我就不需要缓存的数据,清除缓存,使得下次在进入create页面时,重新开始生命周期)删除 Vuex中 arr的值,过100ms在加上(为什么要加上呢?因为删除arr的值后,下次再进入这个页面就不会再被缓存了,也就是说当选择与会人员后,在回到create页面,原来录入的数据就会刷新掉)

实现

keep-alive指令可以将keep-alive中的组件缓存起来,下次访问不开始新的生命周期

路由的配置

  {
    path: "/create",
    name: "create",
    meta: {
      keepAlive: true
    },
    component: appointment
  },

路由的跳转 home页面

	<keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>

Vuex 保存需要缓存的路由

/*
 * @Descripttion:
 * @version:
 * @Author: jsong
 * @Date: 2020-03-26 13:38:38
 * @LastEditors: jsong
 * @LastEditTime: 2020-03-26 21:00:20
 */
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    includeKeepAlive: ["realTime", "appointment"]
  },
  mutations: {
    changeAlive(state, value) {
      const set = new Set(state.includeKeepAlive);
      if (value.option === "d") {
        set.delete(value.name);
      } else {
        set.add(value.name);
      }
      state.includeKeepAlive = [...set];
    }
  }
});

创建会议页面 create

  // 只有添加会诊人员后缓存, 其他不缓存
  beforeRouteLeave(to, from, next) {
    // if (to.name === "contacts") {
    //   // to.meta.keepAlive = true;
    //   this.contactsVue = to;
    //   this.routeNum--;
    //   if (!from.meta.keepAlive) {
    //     from.meta.keepAlive = true;
    //   }
    // } else {
    //   if (this.contactsVue) {
    //     // this.contactsVue.meta.keepAlive = false;
    //   }

    //   from.meta.keepAlive = false;
    //   setTimeout(() => {
    //     from.meta.keepAlive = true;
    //   }, 100);

    //   // this.$destroy();
    // }

    // console.log(this.$store.state.includeKeepAlive);
    if (to.name != "contacts") {
      // this.$destroy();
      console.log(this.$options.name);
      this.$store.commit("changeAlive", {
        name: this.$options.name,
        option: "d"
      });
      setTimeout(() => {
        this.$store.commit("changeAlive", {
          name: this.$options.name,
          option: "a"
        });
      }, 100);
    } else {
      this.routeNum--;
    }
    next();
  },

踩过的坑

  1. 销毁缓存页面$destory ,这样会使这个页面不能再被缓存
  2. 把需要缓存的页面设成false,再改回true,缓存没有清除,下次进入这个页面还是有缓存
  beforeRouteLeave(to, from, next) {
    if (to.name === "contacts") {
      // to.meta.keepAlive = true;
      this.contactsVue = to;
      this.routeNum--;
      if (!from.meta.keepAlive) {
        from.meta.keepAlive = true;
      }
    } else {
      if (this.contactsVue) {
        // this.contactsVue.meta.keepAlive = false;
      }

      from.meta.keepAlive = false;
      setTimeout(() => {
        from.meta.keepAlive = true;
      });

      // this.$destroy();
    }
 }
Logo

前往低代码交流专区

更多推荐