解决vue自定义指令导致的内存泄漏问题


Posted in Javascript onAugust 04, 2020

vue的自定义指令是一个比较容易引起内存泄漏的地方,原因就在于指令通常给元素绑定了事件,但是如果忘记了解绑,就会产生内存泄漏的问题。

看下面代码:

directives: {
  scroll: {
  inserted (el, cb) {
   // 不是元素节点 || 未设置回调函数
   if (el.nodeType !== 1 || !cb) return
   let direct = 'down'
   let rollHeight = 0

   let getScrollEventTarget = (target) => {
   while (target.nodeType === 1 && target.tagName !== 'BODY' && el.tagName !== 'HTML') {
    var overflowY = getComputedStyle(target).overflowY
    if (overflowY === 'scroll' || overflowY === 'auto') {
    return target
    }
    target = target.parentNode
   }
   return window
   }

   let targetNode = getScrollEventTarget(el)

   let scrollListener = () => {
   if (targetNode.scrollTop > rollHeight) {
    direct = 'down'
   } else {
    direct = 'up'
   }
   rollHeight = targetNode.scrollTop
   cb.value(rollHeight, direct)
   }

   el.unbindEventListener = () => {
   targetNode.removeEventListener('scroll', scrollListener)
   }
   targetNode.addEventListener('scroll', scrollListener)
  },
   // unbind (el) {
   // if (el.unbindEventListener) {
   // el.unbindEventListener()
   // }
  // }
  }
 }

起初,我忘记了些注释的unbind方法,导致出现了内存泄漏,给元素绑定的scroll方法,会一直存在内存里。

导致出的情况,就是比如我进了页面滚动到第3页,出去,再点一个页面,当滚动到第4页时,将会请求2次,一次是上个页面的第4页,一次是本次页面的第4页,当你退出,再进一个页面,当滚动到第5页时,将会请求3次(上上页,上页和本页),这就是典型的事件未解绑导致的内存泄漏。

所以需要给元素解绑,好在vue指令提供了unbind钩子函数,

但是这里依然有个技术巧点就是:

1、我们scroll的元素可能是绑定的元素的父级等等,需要一层一层往上找

2、就是解绑的时候我们也需要找到那个父级元素等等,然后还需要remove对应的方法,那么肯定不可能在unbind里再写一次,所以就可以在insert钩子函数里,给el绑定一个解绑事件el.unbindEventListener,在unbind钩子函数里直接调用即可。

以上这篇解决vue自定义指令导致的内存泄漏问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Ext对基本类型的扩展 ext,extjs,format
Dec 25 Javascript
简单的两种Extjs formpanel加载数据的方式
Nov 09 Javascript
javascript实现鼠标放上后下边对应内容变换的效果
Aug 06 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
Sep 22 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
Jan 26 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
Jun 21 Javascript
使用node.js中的Buffer类处理二进制数据的方法
Nov 26 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
Jan 20 Javascript
使用JavaScript实现一个小程序之99乘法表
Sep 21 Javascript
使用JavaScript实现在页面中显示距离2017年中秋节的天数
Sep 26 Javascript
[原创]jquery判断元素内容是否为空的方法
May 04 jQuery
JavaScript原型对象原理与应用分析
Dec 27 Javascript
vue中的v-model原理,与组件自定义v-model详解
Aug 04 #Javascript
详解JS深拷贝与浅拷贝
Aug 04 #Javascript
vue addRoutes路由动态加载操作
Aug 04 #Javascript
vue+element使用动态加载路由方式实现三级菜单页面显示的操作
Aug 04 #Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
Aug 04 #Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
Aug 04 #Javascript
浅谈在vue-cli3项目中解决动态引入图片img404的问题
Aug 04 #Javascript
You might like
php 批量替换程序的具体实现代码
2013/10/04 PHP
php获取文件名后缀常用方法小结
2015/02/24 PHP
PHP执行SQL文件并将SQL文件导入到数据库
2015/09/17 PHP
php动态读取数据清除最右边距的方法
2017/04/12 PHP
php插件Xajax使用方法详解
2017/08/31 PHP
与jquery serializeArray()一起使用的函数,主要来方便提交表单
2011/01/31 Javascript
用JavaScript实现使用鼠标画线的示例代码
2014/08/19 Javascript
jQuery中prependTo()方法用法实例
2015/01/08 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
vue与TypeScript集成配置最简教程(推荐)
2017/10/17 Javascript
详解基于Vue+Koa的pm2配置
2017/10/24 Javascript
详解vue-router 初始化时做了什么
2018/06/11 Javascript
JS中DOM元素的attribute与property属性示例详解
2018/09/04 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
2018/09/17 Javascript
在node中使用jwt签发与验证token的方法
2019/04/03 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
js实现抽奖的两种方法
2020/03/19 Javascript
[03:38]2014DOTA2西雅图国际邀请赛 VG战队巡礼
2014/07/07 DOTA
[01:21:07]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
简单谈谈Python中的元祖(Tuple)和字典(Dict)
2017/04/21 Python
Pandas 数据框增、删、改、查、去重、抽样基本操作方法
2018/04/12 Python
pandas中apply和transform方法的性能比较及区别介绍
2018/10/30 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
Python学习笔记之自定义函数用法详解
2019/06/08 Python
python datetime处理时间小结
2020/04/16 Python
详解如何用HTML5 Canvas API控制图片的缩放变换
2016/03/22 HTML / CSS
Linux如何修改文件和文件夹的权限
2012/06/27 面试题
农业大学毕业生的个人自我评价
2013/10/11 职场文书
考博自荐信
2013/10/25 职场文书
环境卫生标语
2014/06/09 职场文书
五年级学生评语大全
2014/12/26 职场文书
运动会表扬稿范文
2015/05/05 职场文书
欠款起诉书范文
2015/05/19 职场文书
2019公司借款合同范本2篇!
2019/07/24 职场文书
试了下Golang实现try catch的方法
2021/07/01 Golang
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript