解决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 相关文章推荐
jQuery 注意事项 与原因分析
Apr 24 Javascript
Jquery从头学起第四讲 jquery入门教程
Aug 01 Javascript
javascript将浮点数转换成整数的三个方法
Jun 23 Javascript
js控制div弹出层实现方法
May 11 Javascript
JS图片左右无缝隙滚动的实现(兼容IE,Firefox 遵循W3C标准)
Sep 23 Javascript
原生JS实现几个常用DOM操作API实例
Jan 19 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
Dec 05 Javascript
vue 父组件中调用子组件函数的方法
Jun 06 Javascript
ES6 class的应用实例分析
Jun 27 Javascript
vue 解除鼠标的监听事件的方法
Nov 13 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
Dec 06 Javascript
基于element-ui封装表单金额输入框的方法示例
Jan 06 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
天使彦史上最神还原,性别曝光的那一刻,百万网友恋爱了
2020/03/02 国漫
php date与gmdate的获取日期的区别
2010/02/08 PHP
PHP中返回引用类型的方法
2015/04/03 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
javascript获取当前ip的代码
2009/05/10 Javascript
读jQuery之十二 删除事件核心方法
2011/07/31 Javascript
js限制文本框只能输入整数或者带小数点的数字
2015/04/27 Javascript
jquery自定义右键菜单、全选、不连续选择
2016/03/01 Javascript
JSON字符串和对象相互转换实例分析
2016/06/16 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
bootstrap日历插件datetimepicker使用方法
2016/12/14 Javascript
javascript 正则表达式去空行方法
2017/01/24 Javascript
angularjs中的$eval方法详解
2017/04/24 Javascript
Javascript实现页面滚动时导航智能定位
2017/05/06 Javascript
在angular 6中使用 less 的实例代码
2018/05/13 Javascript
Vue中$refs的用法详解
2018/06/24 Javascript
Vue一个案例引发的递归组件的使用详解
2018/11/15 Javascript
利用vue重构有赞商城的思路以及总结整理
2019/02/21 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
JS替换字符串中指定位置的字符(多种方法)
2020/05/28 Javascript
webpack5 联邦模块介绍详解
2020/07/08 Javascript
tornado捕获和处理404错误的方法
2014/02/26 Python
python实现登陆知乎获得个人收藏并保存为word文件
2015/03/16 Python
python mysql断开重连的实现方法
2019/07/26 Python
python实现秒杀商品的微信自动提醒功能(代码详解)
2020/04/27 Python
python 批量将中文名转换为拼音
2021/02/07 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
html5 乒乓球(碰撞检测)实例二
2013/07/25 HTML / CSS
纯净、自信、100%的羊绒服装:360Cashmere
2021/02/20 全球购物
《伯牙绝弦》教学反思
2014/03/02 职场文书
校企合作协议书
2014/04/16 职场文书
初三学习计划书范文
2014/04/30 职场文书
交通工程专业推荐信
2014/09/06 职场文书
【DOTA2】总决赛血虐~ XTREME GAMING vs MAGMA - OGA DOTA PIT 2022 CN
2022/04/02 DOTA