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


Posted in Javascript onMarch 21, 2019

问题产生的背景

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

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

依赖环境

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

定位问题

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

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

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

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

当然,在这块 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 来缓存组件中的数据,当需要重新显示数据时再把数据取出来并重新渲染。当然,这是一个比较大的工程!

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

Javascript 相关文章推荐
jquery实现点击TreeView文本父节点展开/折叠子节点
Jan 10 Javascript
Javascript页面添加到收藏夹的简单方法
Aug 07 Javascript
js仿百度贴吧验证码特效实例代码
Jan 16 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
Feb 13 Javascript
node中socket.io的事件使用详解
Dec 15 Javascript
JSONP之我见
Mar 24 Javascript
angular ng-click防止重复提交实例
Jun 16 Javascript
spirngmvc js传递复杂json参数到controller的实例
Mar 29 Javascript
vue better scroll 无法滚动的解决方法
Jun 07 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
Sep 03 Javascript
js中call()和apply()改变指针问题的讲解
Jan 17 Javascript
微信端调取相册和摄像头功能,实现图片上传,并上传到服务器
May 16 Javascript
基于node简单实现RSA加解密的方法步骤
Mar 21 #Javascript
详解React项目如何修改打包地址(编译输出文件地址)
Mar 21 #Javascript
js实现unicode码字符串与utf8字节数据互转详解
Mar 21 #Javascript
详解JS取出两个数组中的不同或相同元素
Mar 20 #Javascript
详解vue中axios的使用与封装
Mar 20 #Javascript
javascript数组去重方法总结(推荐)
Mar 20 #Javascript
浅谈JavaScript面向对象--继承
Mar 20 #Javascript
You might like
全国FM电台频率大全 - 12 安徽省
2020/03/11 无线电
php更改目录及子目录下所有的文件后缀的代码
2010/09/24 PHP
用PHP实现小写金额转换大写金额的代码(精确到分)
2012/01/10 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
yii2的restful api路由实例详解
2019/05/14 PHP
常用的javascript function代码
2008/05/23 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
2009/12/03 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
JS 修改URL参数(实现代码)
2013/07/08 Javascript
使用jquery获取网页中图片高度的两种方法
2013/09/26 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
微信小程序 地图(map)实例详解
2016/11/16 Javascript
JavaScript仿聊天室聊天记录
2016/12/27 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
2017/10/28 jQuery
JavaScript生成简单等差数列
2017/11/28 Javascript
PHP自动加载autoload和命名空间的应用小结
2017/12/01 Javascript
深入浅析Vue中的slots/scoped slots
2018/04/03 Javascript
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
OpenLayer学习之自定义测量控件
2020/09/28 Javascript
浅析python3中的os.path.dirname(__file__)的使用
2018/08/30 Python
python 获得任意路径下的文件及其根目录的方法
2019/02/16 Python
如何在django中运行scrapy框架
2020/04/22 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
常用的四种CSS透明属性介绍
2014/04/12 HTML / CSS
美国娱乐和流行文化商品店:FYE
2017/09/14 全球购物
Sneaker Studio捷克:购买运动鞋
2018/07/08 全球购物
销售顾问的岗位职责
2013/11/13 职场文书
应聘收银员个人的求职信
2013/11/30 职场文书
求职自荐信怎么写
2015/03/04 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
干货:如何写好工作总结报告!
2019/05/10 职场文书
Python中常见的导入方式总结
2021/05/06 Python
Python基础教程,Python入门教程(超详细)
2021/06/24 Python
Python字符串常规操作小结
2022/04/03 Python
Vue深入理解插槽slot的使用
2022/08/05 Vue.js