解决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 相关文章推荐
js获取div高度的代码
Aug 09 Javascript
JS获得URL超链接的参数值实例代码
Jun 21 Javascript
原生JS实现平滑回到顶部组件
Mar 16 Javascript
每日十条JavaScript经验技巧(二)
Jun 23 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
Dec 01 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
Mar 03 Javascript
vue better-scroll插件使用详解
Jan 25 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
Sep 18 Javascript
详解小程序云开发数据库
May 20 Javascript
原生js添加一个或多个类名的方法分析
Jul 30 Javascript
JS数组方法reduce的用法实例分析
Mar 03 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
Nov 03 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
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
PHP连接MySQL数据的操作要点
2015/03/20 PHP
详解php框架Yaf路由重写
2017/06/20 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
2019/05/05 PHP
javascript 写类方式之七
2009/07/05 Javascript
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
JS的事件绑定深入认识
2014/06/26 Javascript
JS+CSS实现精美的二级导航效果代码
2015/09/17 Javascript
jQuery+ajax读取并解析XML文件的方法
2016/09/09 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
vue.js实现价格格式化的方法
2017/05/23 Javascript
vue+canvas实现炫酷时钟效果的倒计时插件(已发布到npm的vue2插件,开箱即用)
2018/11/05 Javascript
layer弹出层显示在top顶层的方法
2019/09/11 Javascript
使用Vue调取接口,并渲染数据的示例代码
2019/10/28 Javascript
[00:02]DOTA2新版本使用PA至宝后暴击展示
2014/11/19 DOTA
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
python制作一个桌面便签软件
2015/08/09 Python
深入浅析Python传值与传址
2018/07/10 Python
python列表使用实现名字管理系统
2019/01/30 Python
使用python来调用CAN通讯的DLL实现方法
2019/07/03 Python
Python实现数值积分方式
2019/11/20 Python
python3 tkinter实现添加图片和文本
2019/11/26 Python
matplotlib实现显示伪彩色图像及色度条
2019/12/07 Python
浅谈tensorflow 中tf.concat()的使用
2020/02/07 Python
python如何对链表操作
2020/10/10 Python
python语言实现贪吃蛇游戏
2020/11/13 Python
Jupyter Notebook 远程访问配置详解
2021/01/11 Python
python在协程中增加任务实例操作
2021/02/28 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
HTML5新增加标签和功能概述
2016/09/05 HTML / CSS
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
英国著名的美容护肤和护发产品购物网站:Lookfantastic
2020/11/23 全球购物
股东出资证明书范例
2014/10/04 职场文书
Python几种酷炫的进度条的方式
2022/04/11 Python
Java中的Kotlin 内部类原理
2022/06/16 Java/Android