解决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 相关文章推荐
Using the TextRange Object
Oct 14 Javascript
JavaScript中的操作符==与===介绍
Dec 31 Javascript
简介JavaScript中valueOf()方法的使用
Jun 05 Javascript
论JavaScript模块化编程
Mar 07 Javascript
Node.js操作redis实现添加查询功能
May 25 Javascript
jQuery图片加载失败替换默认图片方法汇总
Nov 29 jQuery
微信小程序实现弹出菜单功能
Jun 12 Javascript
实例详解BootStrap的动态模态框及静态模态框
Aug 13 Javascript
vue中选项卡点击切换且能滑动切换功能的实现代码
Nov 25 Javascript
JavaScript创建表格的方法
Apr 13 Javascript
JS脚本实现定时到网站上签到/签退功能
Apr 22 Javascript
原生js实现自定义难度的扫雷游戏
Jan 22 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 date函数参数详解
2006/11/27 PHP
Php图像处理类代码分享
2012/01/19 PHP
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
PHP实现的迷你漂流瓶
2015/07/29 PHP
javascript 动态参数判空操作
2008/12/22 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
JavaScript中的Math 使用介绍
2014/04/21 Javascript
js代码实现的加入收藏效果并兼容主流浏览器
2014/06/23 Javascript
Javascript基础教程之数据类型转换
2015/01/18 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
jQuery实现区域打印功能代码详解
2016/06/17 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
2016/07/14 Javascript
vue双向数据绑定原理探究(附demo)
2017/01/17 Javascript
JS正则替换去空格的方法
2017/03/24 Javascript
第一次记录Bootstrap table学习笔记(1)
2017/05/18 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
vue2.0实现列表数据增加和删除
2020/06/17 Javascript
vue实现路由懒加载的3种方法示例
2020/09/01 Javascript
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
python中string模块各属性以及函数的用法介绍
2016/05/30 Python
python中kmeans聚类实现代码
2018/02/23 Python
从请求到响应过程中django都做了哪些处理
2018/08/01 Python
Django框架实现的分页demo示例
2019/05/25 Python
python flask web服务实现更换默认端口和IP的方法
2019/07/26 Python
Django用户认证系统 User对象解析
2019/08/02 Python
Python手动或自动协程操作方法解析
2020/06/22 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
一款纯css3实现的圆形旋转分享按钮旋转角度可自己调整
2014/09/02 HTML / CSS
CSMA/CD介质访问控制协议
2015/11/17 面试题
客服端调用EJB对象的几个基本步骤
2012/01/15 面试题
大学生职业生涯规划范文
2014/01/22 职场文书
加多宝凉茶广告词
2014/03/18 职场文书
党员一句话承诺大全
2014/03/28 职场文书
如何自己动手写SQL执行引擎
2021/06/02 MySQL
MySQL中varchar和char类型的区别
2021/11/17 MySQL
SQL Server中搜索特定的对象
2022/05/25 SQL Server