vue里如何主动销毁keep-alive缓存的组件

 更新时间:2019年03月21日 10:13:19   作者:old_bin  
这篇文章主要介绍了vue里如何主动销毁keep-alive缓存的组件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

问题产生的背景

我们一个后台,在切换一些标签页的时候,是使用的 keep-alive 缓存的标签页,也使用了 include 属性来决定哪个页面进行缓存,而标签页的切换实际上是路由的切换,也就是说打开一个新标签页的时候,url 会跟着变化,老的标签页如果在 keep-aliveinclude 范围内那就会缓存下来。

然后客服人员就反馈页面开的久了就会崩溃,因为他们基础上不会刷新页面(工作需要),又总有切换标签的习惯,最后导致内存越来越大最后崩溃。

依赖环境

这个项目是基于一个开源 vue 后台框架:https://github.com/PanJiaChen/vue-element-admin,然后代码一直由几个后端开发维护的!所以后端没找出问题在哪,然后就我来接手这个问题了。
写文章时,标签里竟然没有 vue 这一项,差评!

定位问题

先梳理下业务逻辑:从业务场景来说,我们在标签页之间切换时,如果刚进入的这个标签页已被缓存了,那被缓存的标签页就直接拿出来展示就行,而关闭这个标签页的时候就应该销毁对应的组件。

花了点时间查看了一下代码,发现问题在于关闭标签页的时候,虽然这个页面没在 keep-aliveinclude 里了,但是组件也没有被销毁掉,还是在缓存状态,我们可以通过 Vue Devtools 插件看到关闭后的标签页对应的组件一直还存在着:

当然,在这块 keep-alive 本身的逻辑我觉得是没问题的,主要是我们项目比较复杂,缓存的组件太多了而且会一直增加,所以最终导致崩溃。

解决问题

既然问题已经定位了,那就好解决问题了,只需要在关闭标签页的时候把对应的组件也销毁掉就好了。

经过网上一翻查找,发现销毁一个组件可以使用: this.$destroy(‘组件名') 来销毁。

先说下大概思路:keep-aliveinclude 里存的其实是一个 vuex 中的一个数据源(数据源保存的是路由名称),当关闭标签页时,这个数据源中的一项会被移除。这之前,我们在组件里监听到这个数据源的变化,如果此组件对应的路由(这个路由应在 mounted 的时候保存下来)已经不在数据源中了,那就应该销毁此组件。

代码大概如下:

const mixin = {
 data() {
  return {
   routePath: ''
  }
 },
 mounted() {
  this.routePath = this.$route.path
 },
 computed: {
  visitedViews() {
   return this.$store.state.tagsView.visitedViews
  }
 },
 watch: {
  visitedViews(value) {
   if(value 里没有了 routePath 这一项)
    this.$destroy(this.$options.name)
   }
  }
 }
}

export default mixin

这一段代码单独拎出来了,然后在需要缓存的组件里使用 mixins 混入到组件对象中,这样组件中要添加的代码量就比较少了。

更改后经过测试,关闭标签页后对应的组件就会被销毁掉,使用 Vue Devtools 能看的很清楚。

更多思考

在我们后台操作这么频繁的业务场景下,使用 keep-alive 其实并不是一个好的选择。

在我们修复这个问题后,我们通过控制台里的 Memory 查看页面内存的变化时,发现组件即便被销毁,也要经过一段时间才能回收完,当我们在这一段时间一直创建/打开新的标签页时,内存还是会在短时间内高涨。而且有时候,内存在经过一段时间后也并没有回收掉。

keep-alive 本质上是把整个 dom 节点及对应的事件等都缓存下来了,当这样的组件很多的时候,自然会占用很多内存。而如果我们只缓存这个组件中的数据,在需要这个组件再次显示的时候再临时渲染那肯定要节省很多内存的,毕竟数据占的空间其实很小的,而渲染组件要花的时间也不会很长(只要组件不是特别特别复杂)。

所以,下一阶段的优化工作就是把 keep-alive 去掉,然后使用 vuex 来缓存组件中的数据,当需要重新显示数据时再把数据取出来并重新渲染。当然,这是一个比较大的工程!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法

    从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法

    今天小编就为大家分享一篇从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue+Node.js+WebSocket实现即时通讯

    Vue+Node.js+WebSocket实现即时通讯

    本文主要介绍了Vue+Node.js+WebSocket实现即时通讯,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Vue实现简单的跑马灯

    Vue实现简单的跑马灯

    这篇文章主要为大家详细介绍了Vue实现简单的跑马灯,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • Vue3 入口文件createApp函数详解

    Vue3 入口文件createApp函数详解

    这篇文章主要介绍了Vue3 入口文件createApp函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • vuex之this.$store.dispatch()与this.$store.commit()的区别及说明

    vuex之this.$store.dispatch()与this.$store.commit()的区别及说明

    这篇文章主要介绍了vuex之this.$store.dispatch()与this.$store.commit()的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Vue组件之事件总线和消息发布订阅详解

    Vue组件之事件总线和消息发布订阅详解

    这篇文章主要为大家详细介绍了Vue组件之事件总线和消息发布订阅,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • Vue 关闭当前页、关闭当前标签tagsView的实现方法

    Vue 关闭当前页、关闭当前标签tagsView的实现方法

    这篇文章主要介绍了Vue 关闭当前页、关闭当前标签tagsView,主要有两种方式,一种是在vue页面直接实现,另一种在js文件中写自定义函数,在vue页面中调用,本文通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 基于Vue框架vux组件库实现上拉刷新功能

    基于Vue框架vux组件库实现上拉刷新功能

    这篇文章主要为大家详细介绍了基于Vue框架vux组件库实现上拉刷新功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 解决VUE项目在IIS部署出现:Uncaught SyntaxError: Unexpected token < 报错

    解决VUE项目在IIS部署出现:Uncaught SyntaxError: Unexpected&n

    这篇文章介绍了解决VUE项目在IIS部署出现:Uncaught SyntaxError: Unexpected token < 报错的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Vue3基于 rem 比例缩放方案示例详解

    Vue3基于 rem 比例缩放方案示例详解

    这篇文章主要介绍了Vue3基于rem比例缩放方案,本缩放方案置于hooks中即可,文中通过示例代码介绍了vue-cli3 中使用rem布局的方法,需要的朋友可以参考下
    2023-05-05

最新评论