Allen's blog Allen's blog
首页
面经
算法 (opens new window)
分类

Allen

前端CV工程师
首页
面经
算法 (opens new window)
分类
  • Javascript

  • TypeScript

  • CSS

  • Vue

    • Vue样式scoped原理以及样式穿透原理
    • inject响应式怎么做
    • Vue状态管理工具Vuex
    • Vue状态管理工具Pinia
    • Vue重用的组件中使用有状态methods(如防抖)有问题
      • 场景
      • 官方文档有说明
        • 有状态方法
      • 可以帮助理解的文章
    • vue3 props unknown属性上不存在xxx
    • Vuex中的状态如果是引用类型,没有响应式
    • typescript类型Element转化为HTMLElement
  • React

  • 框架和构建工具

  • 工具库

  • 常见业务场景

  • Bug

  • 项目实战

  • 前端
  • Vue
Allen
2023-02-13
目录

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

不过这种方法对于被重用的组件来说是有问题的,因为这个预置防抖的函数是 有状态的:它在运行时维护着一个内部状态。如果多个组件实例都共享这同一个预置防抖的函数,那么它们之间将会互相影响。

要保持每个组件实例的防抖函数都彼此独立,我们可以改为在 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

# 可以帮助理解的文章

  1. 聊一个复用组件中使用 debounce 时遇到的问题 (opens new window)
  2. vue 踩坑小记 - 如何正确的使用 debounce (opens new window)
上次更新: 2023/12/16, 09:22:46
Vue状态管理工具Pinia
vue3 props unknown属性上不存在xxx

← Vue状态管理工具Pinia vue3 props unknown属性上不存在xxx→

最近更新
01
rollup使用配置文件rollup.config.ts打包
12-08
02
package.json导出类型
12-08
03
关键问题方案
11-17
更多文章>
Theme by Vdoing | Copyright © 2023-2023 Allen | Github
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式