vue组件中节流函数的失效的原因和解决⽅法
今天使⽤节流函数的时候遇见了⼀个问题,搞了半天才到原因,所以在这⾥做个总结。
节流函数
浏览器的⼀些事件,如:resize,scroll,mousemove等。这些事件触发频率太过频繁,绑定在这些事件上的回调函数会不停的被调⽤,加重浏览器的负担,导致⽤户体验⾮常糟糕。所以先贤们发明了节流函数,简单版本如下:
function throttle (f, wait = 200) {
let last = 0
return function (...args) {
let now = w()
if (now - last > wait) {
last = now
f.apply(this, args)
}
}
}
假设有⼀个 vue 组件 svgMark。这个组件中渲染的元素要在页⾯窗⼝⼤⼩发⽣变化时重绘 reDraw ,⽽重绘时要使⽤节流函数防⽌性能损耗。正常情况下代码如下:
<template>
<div>{{ index }}</div>
</template>
<script>
import { throttle } from 'lodash'
export default {
name: 'SvgMark',
data() {
return {
index: 0
}
},
mounted() {
window.addEventListener('resize', Draw)lodash有哪些方法
},
beforeDestroy() {
},
methods: {
reDraw: throttle(function() {
this.index++
}, 500)
}
}
</script>
</script>
⼀般情况下这样⽤没什么问题。但是有这样⼀个场景,使⽤节流函数时却失效了,即当这个组件被 v-for 循环加载了很多次:
<template>
<div>
<svgMark v-for="item in 10" :key="item.id" />
</div>
</template>
这个时候⽆论渲染了多少个 svgMark 组件,在窗⼝⼤⼩改变的时候却只触发了第⼀个组件和第 n 割组件的重绘,为什么其他组件没有触发呢?这就要从头说起了。
节流函数
节流函数在初始化的时候产⽣了⼀个闭包,闭包内保存了变量 last ,这个 last 记录了上⼀次执⾏ f 函数的时间。⽽当下⼀次触发节流函数的时候,如果此时时间 now 减去上次时间 last ⼩于了我们规定的节流时间 wait ,那么函数 f 将不会执⾏。
很显然,第⼀个⼦组件在触发节流函数的时候产⽣了⼀个 last,⽽第⼆个组件在触发节流函数时候的时产⽣的 now 并没有满⾜ now - last > wait 的条件,所以没有执⾏重绘代码。⽽到了第 n 个组件触发节流函数的时候,满⾜了 now - last > wait 的条件所以重绘成功了。
vue 组件
vue 组件在代码编译的阶段,组件 svgMark 中的⽅法 reDraw: throttle(function() { this.index++ }, 500) 就已经被编译成了类似如下函数:
reDraw: ƒ (...args) {
let now = w()
if (now - last > wait) {
last = now
f.apply(this, args)
}
}
由于函数是引⽤类型,所有使⽤⼦组件 svgMark 的 methods 中的 reDraw 都指向了同⼀个内存地址,也就是说所有⼦组件的reDraw ⽅法都是同⼀个函数。
因为所有组件都公⽤了同⼀个节流函数,当然就会产⽣节流了。那怎么解决问题呢?对症下药就要让每个组件产⽣⾃⼰的节流函数,⽽不产⽣共⽤。代码如下
⼦组件:
<template>
<div>{{ index }}</div>
</template>
<script>
import { throttle } from 'lodash'
export default {
name: 'SvgMark',
data() {
return {
index: 0
}
},
mounted() {
this.index++
}, 500)
window.addEventListener('resize', Draw)
},
beforeDestroy() {
}
}
</script>
我们在 mounted 声明周期函数中⼿动声明了 reDraw 函数替代 methods 中的 reDraw ,这样在每个组件初始化的时候都会产⽣⼀个⾃⼰的节流函数了。需要注意此时节流函数的参数使⽤了箭头函数,因为这样 this 才会指向组件实例。
以上就是节流函数带给我的坑,现在分享给⼤家。[下班][⿎掌]
以上就是vue组件中节流函数的失效和解决⽅法的详细内容,更多关于vue 组件节流函数的资料请关注其它相关⽂章!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论