- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章vue组件中节流函数的失效的原因和解决方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
今天使用节流函数的时候遇见了一个问题,搞了半天才找到原因,所以在这里做个总结.
节流函数 。
浏览器的一些事件,如:resize,scroll,mousemove等。这些事件触发频率太过频繁,绑定在这些事件上的回调函数会不停的被调用,加重浏览器的负担,导致用户体验非常糟糕。所以先贤们发明了节流函数,简单版本如下:
1
2
3
4
5
6
7
8
9
10
|
function
throttle (f, wait = 200) {
let last = 0
return
function
(...args) {
let now = Date.now()
if
(now - last > wait) {
last = now
f.apply(
this
, args)
}
}
}
|
假设有一个 vue 组件 svgMark。这个组件中渲染的元素要在页面窗口大小发生变化时重绘 reDraw ,而重绘时要使用节流函数防止性能损耗。正常情况下代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<
template
>
<
div
>{{ index }}</
div
>
</
template
>
<
script
>
import { throttle } from 'lodash'
export default {
name: 'SvgMark',
data() {
return {
index: 0
}
},
mounted() {
window.addEventListener('resize', this.reDraw)
},
beforeDestroy() {
window.removeEventListener('resize', this.reDraw)
},
methods: {
reDraw: throttle(function() {
this.index++
}, 500)
}
}
</
script
>
</
script
>
|
一般情况下这样用没什么问题。但是有这样一个场景,使用节流函数时却失效了,即当这个组件被 v-for 循环加载了很多次:
1
2
3
4
5
|
<
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 组件在代码编译的阶段,组件 svgMark 中的方法 reDraw: throttle(function() { this.index++ }, 500) 就已经被编译成了类似如下函数:
1
2
3
4
5
6
7
|
reDraw: ƒ (...args) {
let now = Date.now()
if
(now - last > wait) {
last = now
f.apply(
this
, args)
}
}
|
由于函数是引用类型,所有使用子组件 svgMark 的 methods 中的 reDraw 都指向了同一个内存地址,也就是说所有子组件的 reDraw 方法都是同一个函数.
因为所有组件都公用了同一个节流函数,当然就会产生节流了。那怎么解决问题呢?对症下药就要让每个组件产生自己的节流函数,而不产生共用。代码如下 。
子组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<
template
>
<
div
>{{ index }}</
div
>
</
template
>
<
script
>
import { throttle } from 'lodash'
export default {
name: 'SvgMark',
data() {
return {
index: 0
}
},
mounted() {
this.reDraw = throttle(() => {
this.index++
}, 500)
window.addEventListener('resize', this.reDraw)
},
beforeDestroy() {
window.removeEventListener('resize', this.reDraw)
}
}
</
script
>
|
我们在 mounted 声明周期函数中手动声明了 reDraw 函数替代 methods 中的 reDraw ,这样在每个组件初始化的时候都会产生一个自己的节流函数了。需要注意此时节流函数的参数使用了箭头函数,因为这样 this 才会指向组件实例.
以上就是节流函数带给我的坑,现在分享给大家。[下班][鼓掌] 。
以上就是vue组件中节流函数的失效和解决方法的详细内容,更多关于vue 组件节流函数的资料请关注我其它相关文章! 。
原文链接:https://juejin.cn/post/6901231253102526477?utm_source=tuicool&utm_medium=referral 。
最后此篇关于vue组件中节流函数的失效的原因和解决方法的文章就讲到这里了,如果你想了解更多关于vue组件中节流函数的失效的原因和解决方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private成员。 上面描述了private修饰符的基本职能,今天来
我是 JWT 的新手,想知道当用户退出应用程序时是否可以在服务器端使 JWT 失效/作废(我也想知道它是否有意义 这样做!)。思路是: 用户点击其应用中的注销链接 应用调用 POST https://
是否有可能使特定操作的 PageCache 无效或删除。 考虑一下: class SiteController extends Controller { public function beh
我使用的是 XCode 9,OSX 而不是 iOS,Objective-C。 我有一个 XPC 服务可以与其他应用程序通信。 XPC 服务对我来说是全新的。我已经阅读了我找到的文档和文章 - 我仍然需
我有一个带有 NSTimer 的 iPhone 应用程序,名为 pressTimer,每当有人触摸此按钮时,该应用程序就会关闭。问题是他们经常触摸按钮,我希望计时器在他们抬起手指时停止。因此,我在 .
session 失效意味着 session 销毁。所以如果 session 被销毁,则表明服务器无法识别之前访问过的客户端。因此现在它为该客户端创建一个新的 session ID。 这是正确的吗?如果
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我在尝试缓存 WebClient 返回的 Mono 时遇到问题。代码是这样的: public Mono authenticate() { return cachedTokenMono = ca
我知道通过在 DD-web.xml 文件中设置超时期限来使 session 失效,但我想知道如何以编程方式使 session 失效? 最佳答案 不确定你是否用java编程,但是部署描述符web.xml
我在 2 个不同的服务器上有 2 个应用程序 - Tomcat(基本上是一个 .WAR 文件)和一个在 jBoss 中的 EAR。 EAR 是一个可重复使用的应用程序,我将在其中对用户进行身份验证并将
self.timerProgress=[NSTimer scheduledTimerWithTimeInterval:50.0 target:self selector:@selector(stopP
在我的应用程序中,我应该使用多个计时器,但我不想为每个函数添加单独的计时器,我如何创建一个函数来简化创建多个计时器的过程,我尝试了下面的这段代码,它可以工作,但我不能使计时器无效。 import UI
我在 Swift 中做了一个练习项目来学习 NSTimer 是如何工作的。一键启动定时器,一键取消定时器。当我点击每个按钮一次时它工作正常。但是,当我多次点击开始计时器按钮时,我无法再使其无效。 这是
我在清理事件时遇到一个问题。当我从应用程序注销时,我可以执行清理事件以及 session.invalidate()。但是,当我关闭浏览器选项卡或关闭浏览器时,我无法进行干净的事件。我已经为此阅读了很多
我在 7.1.1 的 Google Pixel 设备上进行测试,发现当所有指纹从设备上移除时,我的私钥并未失效。我已经按照演示应用程序使用单个对称 SecretKey 进行了测试并且按预期工作,但是使
我正在 Tomcat 中运行一个 J2EE Web 应用程序,最近我的任务是向该应用程序添加指标。我正在使用 SessionListener 来检测 session 何时被销毁,然后将指标上传到数据库
我通过右键单击项目 -> 应用程序 -> 程序集信息 -> 标题修改了我的 C# 应用程序名称。 如果应用程序已经安装,则它不会更新名称,因为它正在从未刷新的 MUICache 中提取应用程序名称。
我正在使用 AssetsLibrary 框架将 Assets 保存到特定相册 (ALAssetsGroup)。 由于我经常使用 ALAssetsGroup(用于我想保存 Assets 的专辑),我认为
我的应用程序中有 4 个 NSTimers 对象,它们每隔几秒就会向一个 rest URL 发出请求。 点击一个特定的按钮我想停止计时器,这样它就停止轮询,点击另一个按钮我想恢复轮询。 我已经为所有计
我正在开发一个使用 JWT token 身份验证的 API。我在其背后创建了一些逻辑来使用验证码等更改用户密码。 一切正常,密码已更改。但这里有一个问题:即使用户密码已更改并且我在验证时获得了新的 J
我是一名优秀的程序员,十分优秀!