$nextTick()在什么时候DOM已经更新了

135 阅读2分钟

前言

在Vue官网之响应式基础

DOM 更新时机

当你修改了响应式状态时,DOM 会被自动更新。但是需要注意的是,DOM 更新不是同步的。Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次。

要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API:

js

import { nextTick } from 'vue'

export default {
  methods: {
    async increment() {
      this.count++
      await nextTick()
      // 现在 DOM 已经更新了
    }
  }
}

防抖与节流

防抖就是你点击一次就会触发一次,节流你点击无数次他只能给你触发一次按钮

举个案例:

输入的时候要实时搜索,如果每输一个字就马上搜,服务器压力会非常大,延迟段时间再去搜索,防抖点击一次就会立马执行,但是用一个异步函数给他做个没点击一次三秒过后再执行,一个搜索引擎 最多执行一次,这是我理解的节流,再用一个lodash做一个异步封装,三秒后再执行结束

有状态方法

在某些情况下,我们可能需要动态地创建一个方法函数,比如创建一个预置防抖的事件处理器:

js

import { debounce } from 'lodash-es'

export default {
  methods: {
    // 使用 Lodash 的防抖函数
    click: debounce(function () {
      // ... 对点击的响应 ...
    }, 500)
  }
}

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

要保持每个组件实例的防抖函数都彼此独立,我们可以改为在 created 生命周期钩子中创建这个预置防抖的函数:

js

export default {
  created() {
    // 每个实例都有了自己的预置防抖的处理函数
    this.debouncedClick = _.debounce(this.click, 500)
  },
  unmounted() {
    // 最好是在组件卸载时
    // 清除掉防抖计时器
    this.debouncedClick.cancel()
  },
  methods: {
    click() {
      // ... 对点击的响应 ...
    }
  }
}