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 相关文章推荐
在IE浏览器中resize事件执行多次的解决方法
Jul 12 Javascript
解析DHTML,JavaScript,DOM,BOM以及WEB标准的描述
Jun 19 Javascript
Js 获取当前函数参数对象的实现代码
Jun 20 Javascript
jQuery EasyUI提交表单验证
Jul 19 Javascript
JS上传图片预览插件制作(兼容到IE6)
Aug 07 Javascript
使用Javascript监控前端相关数据的代码
Oct 27 Javascript
微信公众平台开发教程(五)详解自定义菜单
Dec 02 Javascript
vue-cli创建的项目,配置多页面的实现方法
Mar 15 Javascript
React styled-components设置组件属性的方法
Aug 07 Javascript
微信小程序多音频播放进度条问题
Aug 28 Javascript
jquery UI实现autocomplete在获取焦点时得到显示列表功能示例
Jun 04 jQuery
layui之数据表格--与后台交互获取数据的方法
Sep 29 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
PHP 服务器配置(使用Apache及IIS两种方法)
2009/06/01 PHP
php的hash算法介绍
2014/02/13 PHP
分享最受欢迎的5款PHP框架
2014/11/27 PHP
php判断手机浏览还是web浏览,并执行相应的动作简单实例
2016/07/28 PHP
手把手编写PHP框架 深入了解MVC运行流程
2016/09/19 PHP
javascript与CSS复习(《精通javascript》)
2010/06/29 Javascript
NodeJS学习笔记之Connect中间件模块(二)
2015/01/27 NodeJs
使用js实现的简单拖拽效果
2015/03/18 Javascript
复杂的javascript窗口分帧解析
2016/02/19 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
Angular.js中$apply()和$digest()的深入理解
2016/10/13 Javascript
实例解析js中try、catch、finally的执行规则
2017/02/24 Javascript
jQuery实现三级联动效果
2017/03/02 Javascript
移动端手指放大缩小插件与js源码
2017/05/22 Javascript
获取url中用&隔开的参数实例(分享)
2017/05/28 Javascript
解决vue中监听input只能输入数字及英文或者其他情况的问题
2018/08/30 Javascript
JavaScript基础之this和箭头函数详析
2019/09/05 Javascript
js实现图片区域可点击大小随意改变(适用移动端)代码实例
2019/09/11 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
python中关于日期时间处理的问答集锦
2013/03/08 Python
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
python分析nignx访问日志脚本分享
2015/02/26 Python
Python正则表达式匹配中文用法示例
2017/01/17 Python
用不到50行的Python代码构建最小的区块链
2017/11/16 Python
Python aiohttp百万并发极限测试实例分析
2019/10/26 Python
python求最大公约数和最小公倍数的简单方法
2020/02/13 Python
Django用户认证系统如何实现自定义
2020/11/12 Python
python 实现数据库中数据添加、查询与更新的示例代码
2020/12/07 Python
html5文字阴影效果text-shadow使用示例
2013/07/25 HTML / CSS
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
企业员工薪酬方案
2014/06/04 职场文书
文化产业实施方案
2014/06/07 职场文书
2015入党个人自传范文
2015/06/26 职场文书
Valheim服务器 Mod修改安装教程 【ValheimPlus】
2022/12/24 Servers