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 相关文章推荐
JavaScript 组件之旅(三):用 Ant 构建组件
Oct 28 Javascript
jQuery中判断一个元素是否为另一个元素的子元素(或者其本身)
Mar 21 Javascript
解决node.js安装包失败的几种方法
Sep 02 Javascript
9个让JavaScript调试更简单的Console命令
Nov 14 Javascript
微信小程序 九宫格实例代码
Jan 21 Javascript
bootstrap-table.js扩展分页工具栏(增加跳转到xx页)功能
Dec 28 Javascript
JavaScript实现微信红包算法及问题解决方法
Apr 26 Javascript
vue.js 双层嵌套for遍历的方法详解, 类似php foreach()
Sep 07 Javascript
浅谈Vue.js 中的 v-on 事件指令的使用
Nov 25 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
May 01 Javascript
JQuery实现ul中添加LI和删除指定的Li元素功能完整示例
Oct 16 jQuery
JS前端使用canvas实现扩展物体类和事件派发
Aug 05 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 编程安全性小结
2010/01/08 PHP
使用PHP实现微信摇一摇周边红包
2016/01/04 PHP
Javascript开发包大全整理
2006/12/22 Javascript
如何使用jquery动态加载js,css文件实现代码
2013/04/03 Javascript
JavaScript对HTML DOM使用EventListener进行操作
2015/10/21 Javascript
深入解析JavaScript中的数字对象与字符串对象
2015/10/21 Javascript
前端jquery部分很精彩
2016/05/03 Javascript
AngularJS控制器详解及示例代码
2016/08/16 Javascript
jq实现左滑显示删除按钮,点击删除实现删除数据功能(推荐)
2016/08/23 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
2017/05/07 Javascript
vue-router的使用方法及含参数的配置方法
2018/11/13 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
2019/04/15 Javascript
小程序跨页面交互的作用与方法详解
2020/01/07 Javascript
[02:30]辉夜杯主赛事第二日胜者组半决赛 CDEC.Y赛后采访
2015/12/26 DOTA
Python 解析XML文件
2009/04/15 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
2018/05/16 Python
解决matplotlib库show()方法不显示图片的问题
2018/05/24 Python
Python玩转加密的技巧【推荐】
2019/05/13 Python
python实现集中式的病毒扫描功能详解
2019/07/09 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
python 调试冷知识(小结)
2019/11/11 Python
Python视频编辑库MoviePy的使用
2020/04/01 Python
python开发一个解析protobuf文件的简单编译器
2020/11/17 Python
Python爬虫之Selenium多窗口切换的实现
2020/12/04 Python
图解CSS3制作圆环形进度条的实例教程
2016/05/26 HTML / CSS
Fanatics法国官网:美国体育电商
2019/08/27 全球购物
如何选择使用结构还是类
2014/05/30 面试题
社区党员志愿服务活动方案
2014/08/18 职场文书
校园会短篇的广播稿
2014/10/21 职场文书
2015年国庆节慰问信
2015/03/23 职场文书
史上最牛辞职信
2015/05/13 职场文书
祝福语集锦:给百岁老人祝寿贺词
2019/11/19 职场文书
如何自己动手写SQL执行引擎
2021/06/02 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
2022/07/15 MySQL