Vue重用的组件中使用有状态methods(如防抖)有问题
# 场景
在一个页面中有多个复用的 Vue 组件,每个组件都是单独的实例,但是每个组件实例的 methods 处理方式是代理,比如 A 组件调用方法 fn,实际上是在调用 methods 对象中的 fn,每个实例都会调用同一个 fn,如果这个 fn 是有状态的,比如防抖函数内部有一个 timer,此时复用的组件之间就会产生影响。
# 官方文档有说明
# 有状态方法 (opens new window)
在某些情况下,我们可能需要动态地创建一个方法函数,比如创建一个预置防抖的事件处理器:
import { debounce } from 'lodash-es'
export default {
methods: {
// 使用 Lodash 的防抖函数
click: debounce(function () {
// ... 对点击的响应 ...
}, 500)
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
不过这种方法对于被重用的组件来说是有问题的,因为这个预置防抖的函数是 有状态的:它在运行时维护着一个内部状态。如果多个组件实例都共享这同一个预置防抖的函数,那么它们之间将会互相影响。
要保持每个组件实例的防抖函数都彼此独立,我们可以改为在 created 生命周期钩子中创建这个预置防抖的函数:
export default {
created() {
// 每个实例都有了自己的预置防抖的处理函数
this.debouncedClick = _.debounce(this.click, 500)
},
unmounted() {
// 最好是在组件卸载时
// 清除掉防抖计时器
this.debouncedClick.cancel()
},
methods: {
click() {
// ... 对点击的响应 ...
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 可以帮助理解的文章
上次更新: 2023/12/16, 09:22:46