vue keepAlive 缓存指定页面

文章介绍了一种使用Vue的keepAlive特性来实现页面缓存的方法,特别是在A页面进入B页面保持缓存,但进入C页面时不缓存A页面。通过创建mixins文件,定义init和onSearch事件来处理页面初始化和详情页返回时的数据刷新。同时,使用beforeRouteEnter和beforeRouteLeave路由守卫来控制缓存行为,并提供了一个强制清除缓存的函数。
摘要由CSDN通过智能技术生成

vue 利用 keepAlive 达到 a页面进入b页面缓存,但是进入c页面不会缓存该a页面

  • 创建一个 mixins 文件,完成该页面功能
  • 注意:
    • 初始化事件不能再放置在created 、mounted 事件中了,需要自己写一个init事件
    • bug: 进入详情页再进入其他页面,重新进入该页面,该页面状态依旧被保存,执行 onSearch 事件
    • 优化: 强制清除该页面得keepAlive缓存(如果你不需要出去页面清除缓存,并且可以存在多个keepAlive页面,只是做进入该页面得刷新,可以删除 beforeRouteLeave 路由守卫)
export default {
  data() {
    return {
      isFirstEntry: true,
      // 离开该组件keepAlive状态存在的页面路径
      isKeepAliveRouterList: [],
    };
  },

  created() {},

  activated() {
    // 如果指定页面返回,并且是页面指定状态,马上重新按照条件查询一次
    if (this.$route.meta.isBack) {
      if (this.isFirstEntry) {
        this.isFirstEntry = false;
        this.init();
      } else this.onSearch();
    } else {
      // 第一次和非详情页进入页面时 isBack都为false,即需要重新请求数据
      if (this.isFirstEntry) this.isFirstEntry = false;
      this.init();
    }
  },

  methods: {
    init() {
      console.log(
        "页面初次进入刷新所有数据,如果该提示存在,你的页面不存在init函数!"
      );
    },
    onSearch() {
      console.log(
        "详情页跳回该页面,如果该提示存在,你的页面不存在onSearch函数,查看页面是否需要按照当前条件刷新!"
      );
    },
    // 获取可以缓存的路径数组
    setIsKeepAliveRouterList(routeMeta, that) {
      let isKeepAliveRouterList = [];
      if (
        routeMeta.isKeepAliveRouterList &&
        Array.isArray(routeMeta.isKeepAliveRouterList)
      ) {
        isKeepAliveRouterList = [
          ...routeMeta.isKeepAliveRouterList,
          ...that.isKeepAliveRouterList,
        ];
      } else {
        isKeepAliveRouterList = [...that.isKeepAliveRouterList];
      }
      return isKeepAliveRouterList;
    },
    // 手动控制keepAlive的强制清除缓存功能
    removeKeepAliveCacheForVueInstance(vueInstance) {
      // 获取当前组件的key值
      let key =
        vueInstance.$vnode.key ??
        vueInstance.$vnode.componentOptions.Ctor.cid +
          (vueInstance.$vnode.componentOptions.tag
            ? `::${vueInstance.$vnode.componentOptions.tag}`
            : "");
      // vueInstance.$vnode.key !== null && vueInstance.$vnode.key !== undefined
      //  ? vueInstance.$vnode.key
      //  : vueInstance.$vnode.componentOptions.Ctor.cid +
      //    (vueInstance.$vnode.componentOptions.tag ? `::${vueInstance.$vnode.componentOptions.tag}` : '');

      // 拿到keep-alive的cache,向上取一层拿到keep-alive的cache
      let cache = vueInstance.$vnode.parent.componentInstance.cache;
      // 拿到keep-alive的keys
      let keys = vueInstance.$vnode.parent.componentInstance.keys;
      if (cache[key]) {
        // 缓存删除了,顺便也让当前组件销毁
        vueInstance.$destroy();
        delete cache[key];
        let index = keys.indexOf(key);
        if (index > -1) {
          keys.splice(index, 1);
        }
      }
    },
  },

  // 导航进入该组件
  beforeRouteEnter(to, from, next) {
    next((vm) => {
      let isKeepAliveRouterList = vm.setIsKeepAliveRouterList(to.meta, vm);

      if (isKeepAliveRouterList.includes(from.path)) {
        to.meta.isBack = true;
      } else {
        to.meta.isBack = false;
      }
    });
  },

  // 导航离开该组件的对应路由时调用
  beforeRouteLeave(to, from, next) {
    let isKeepAliveRouterList = this.setIsKeepAliveRouterList(from.meta, this);

    if (!isKeepAliveRouterList.includes(to.path)) {
      // 退出到非指定页面,清除该keepAlive缓存
      this.isFirstEntry = true;
      this.removeKeepAliveCacheForVueInstance(this);
      // 退出到非指定页面,销毁页面,该方法没有清除缓存,可能会导致页面销毁了,但是keepalive依旧存在缓存
      // this.$destroy();
      // this.$el.parentNode.removeChild(this.$el);
    }

    next();
  },
};
  • route.js 文件中配置路由信息
export default [
	{
		path: '/a',
		name: 'A',
		component: () => import('@/a'),
		// 用于在keepAlive中控制当前页面需要缓存,并且配置了 进入指定路径页面可缓存得数组
		meta: { keepAlive: true, isBack: false, isKeepAliveRouterList: ['/b'] }
	}
]
  • router-view 配置
// max: 最大可keepAlive的页面数量
<keep-alive max="1" >
	<router-view v-if="this.$route.meta.keepAlive" :key="$route.path"/>
</keep-alive>
 <router-view v-if="!this.$route.meta.keepAlive" />
### 回答1: Vue页面keep-alive缓存可以通过以下方法清除: 1. 在组件中使用activated钩子函数,手动清除缓存: ``` activated() { this.$nextTick(() => { this.$refs.keepAliveComponent && this.$refs.keepAliveComponent.clearCache() }) } ``` 2. 在路由配置中使用meta属性,设置需要清除缓存的路由: ``` { path: '/example', name: 'example', component: Example, meta: { keepAlive: false // 设置为false表示不缓存该路由 } } ``` 3. 在组件中使用$route.meta.keepAlive属性,动态设置是否缓存: ``` <template> <div v-if="$route.meta.keepAlive">需要缓存的组件</div> <div v-else>不需要缓存的组件</div> </template> ``` 以上是清除Vue页面keep-alive缓存的方法,希望能对你有所帮助。 ### 回答2: Vue中的keep-alive组件可以缓存组件实例,当组件被切换隐藏时,它的状态将被保留,就像在内存中一样。但是,我们会发现在一些情况下,我们需要手动清除keep-alive缓存,以便重新渲染组件。 在Vue中,可以通过以下方式清除keep-alive缓存: 1. keep-alive组件内部方法: 通过在keep-alive组件的内部定义一个clear方法,我们可以手动清除缓存。 例如: <keep-alive ref="keepAlive"> <router-view></router-view> </keep-alive> methods: { clearCache() { this.$refs.keepAlive.cache = {} // 或者用this.$refs.keepAlive.$options.cache = {}, 这两种方法都可以手动清除缓存。 } } 这里,我们通过向keep-alive组件添加ref="keepAlive"来获取组件引用。然后在methods内部定义了一个clearCache方法来清除缓存。在Vue 2.3.0+版本中,keepAlive组件提供了cache属性来存储keepAlive组件缓存,我们可以通过this.$refs.keepAlive.cache={};清空缓存。 2. router钩子函数: 除了在keep-alive组件内部定义clear方法以外,我们还可以通过在router的钩子函数中实现缓存的清除。 例如: const router = new VueRouter({ routes: [ { path: '/', component: Home, meta: { keepAlive: true } }, { path: '/about', component: About } ] }) router.beforeEach((to, from, next) => { if (!to.meta.keepAlive) { clearKeepAliveCache(); } next(); }) function clearKeepAliveCache() { const cache = this.$options.cache; //获取keepAlive缓存对象 Object.keys(cache).forEach(key => { cache[key].instance.$destroy(); //销毁实例 delete cache[key]; //删除缓存 }); } 我们在VueRouter对象的routes选项中定义了meta.keepAlive属性来判断该路由是否需要缓存。接着在router.beforeEach钩子函数中通过判断meta.keepAlive,来决定是否清除keep-alive缓存。调用clearKeepAliveCache函数清除缓存。 清除缓存时,我们需要销毁实例,以避免内存泄漏。 以上是清除Vue 页面keepalive缓存的两种方法,尽管官方文档推荐第一种方法,但是当我们在不同的路由之间切换时,第二种方法较为灵活。 ### 回答3: vue页面中使用keep-alive指令会使得页面缓存,这种缓存机制可以提高页面的性能和用户体验。但是在一些特定的场景下,需要手动清除页面缓存以达到更好的效果。这篇文章将介绍如何清除vue页面中的缓存。 一、全局清除 可以使用以下两种方法来清除vue页面缓存。 方法1:调用$destroy()方法 在需要清除页面缓存的地方,通过访问Vue的根实例,可以得到keep-alive组件的实例。调用该实例的$destroy()方法即可清除缓存,以下是示例代码: ```javascript this.$root.$children[0].$children.find(item => item.$options.name==='keep-alive').$destroy() ``` 方法2:使用del命令 del命令可以同样实现页面缓存清除功能,这种方法只需要设置对应keep-alive组件的include属性为空数组,如下所示: ```javascript let keepAliveComponentList = this.$refs.keepAlive keepAliveComponentList.forEach(component => { component.include = [] }) ``` 二、局部清除 需要注意的是,全局清除会将所有的vue页面缓存清除,这样会带来繁琐的操作和不必要的性能消耗。因此,推荐使用局部清除来清除vue页面缓存。 下面是一个实现局部清除的示例: ```html <template> <div> <!-- 1. 绑定 $route 参数 --> <keep-alive :include="keepAliveList"> <router-view :key="$route.fullPath"/> </keep-alive> </div> </template> <script> export default { data() { return { keepAliveList: ["home"] } }, created() { let currentName = this.$route.name this.keepAliveList.push(currentName) }, // 2. 监听 $route 对象 watch: { $route(newVal, oldVal) { if (this.keepAliveList.indexOf(newVal.name) === -1) { this.keepAliveList.push(newVal.name) } if (this.keepAliveList.indexOf(oldVal.name) !== -1) { this.keepAliveList.splice(this.keepAliveList.indexOf(oldVal.name), 1) } } } } </script> ``` 以上代码中,我们通过将已经访问过的页面名称加入数组keepAliveList中,然后将该数组绑定到keep-alive组件的include属性上,只有在该数组内的页面才会被keep-alive缓存,不在数组内的页面将会在跳转的时候被销毁。 总结: 缓存机制是前端优化中的一个重要环节,适当的使用keep-alive组件可以减少服务器的压力,提高页面性能。但是在实际应用中,我们需要考虑到缓存的清除问题,根据不同的应用场景,选择全局清除还是局部清除,以最优化的体验来满足用户需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值