vue的生命周期和nextTick的关系

一、Vue.js 的生命周期

什么是生命周期?

Vue 组件从创建、更新到销毁,会经历一系列的过程,这些过程称为组件的生命周期。Vue 提供了多个生命周期钩子(hook),让我们在组件的不同阶段执行特定的逻辑。

主要的生命周期钩子:

  • beforeCreate:实例初始化之后,数据观测和事件配置之前。
  • created:实例创建完成,属性已绑定,但 DOM 未生成,$el 还不可用。
  • beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。
  • mounted:实例挂载完成,el 被新创建的 vm.$el 替换,并挂载到实例上,此时 DOM 可访问。
  • beforeUpdate:响应式数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
  • updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。
  • beforeDestroy/beforeUnmount:实例销毁之前调用。
  • destroyed/unmounted:实例销毁后调用。

二、什么是 nextTick

nextTick 的作用:

  1. 异步 DOM 更新机制:Vue 在数据变化后,不会立即同步更新 DOM,而是将其放入一个队列,在下一个事件循环(Tick)中执行 DOM 更新。这是为了优化性能,避免频繁的 DOM 操作。

  2. nextTick 方法 :提供一个回调函数,在下次 DOM 更新循环结束后执行。确保在数据变化导致的 DOM 更新完成后,再执行某些操作

    javascript 复制代码
    // vue3 的写法
    nextTick(()=>{
    //需异步执行的内容
    })
    
    // nextTick 基于微任务队列:Promise.resolve().then()、MutationObserver 等。
    // 确保在 DOM 更新后执行回调:将回调函数放入微任务队列,等待 DOM 更新完成后立即执行

nextTick 的使用:

  1. 实例方法this.$nextTick(callback)
  2. 全局方法Vue.nextTick(callback)

三、生命周期与 nextTick 的关系

生命周期钩子中的 DOM 状态

**beforeCreate**阶段

  • 特点:数据和方法还未初始化,无法操作DOM节点。

created 阶段

  • 特点 :实例已经创建,数据和方法已初始化,但未进行 DOM 渲染,this.$el 还不可用。
  • 注意:此时无法进行与 DOM 有关的操作。

mounted 阶段

  • 特点 :组件已挂载,this.$el 可用,初始渲染完成。
  • 注意:可以访问和操作组件的 DOM 元素。

updated 阶段

  • 特点:组件数据更新后,DOM 重新渲染并打补丁,此时已完成 DOM 更新。
  • 注意:可以获取更新后的 DOM 状态。

需要使用 nextTick 的场景

在数据更新后,立即想操作更新后的 DOM 元素

  • 问题:由于 DOM 更新是异步的,数据更新后,DOM 还未更新,直接操作会得到旧的 DOM 状态。
  • 解决 :使用 this.$nextTick,确保在 DOM 更新完成后再执行操作。

在生命周期钩子中需要等待 DOM 更新

  • mounted 钩子中 ,初始 DOM 已渲染完成,可以直接操作 DOM,一般不需要 nextTick

    javascript 复制代码
    mounted() {
      // 可以直接访问 DOM
      console.log(this.$refs.myElement.offsetHeight);
    }
  • updated 钩子中 ,DOM 已更新完毕,DOM 是最新的,也不需要 nextTick

    javascript 复制代码
    updated() {
      // DOM 已更新,可以直接操作
      console.log(this.$refs.myElement.offsetHeight);
    }
  • 在beforeUpdate 钩子中,组件的数据已变化,但 DOM 还未更新,需使用nextTick。

    javascript 复制代码
    beforeUpdate() {
      // 数据已更新,DOM 还未更新
      this.$nextTick(() => {
        // DOM 更新后执行
        console.log(this.$refs.myElement.offsetHeight);
      });
    }
  • 在数据更新后,需要在下一次更新前执行操作 ,需要使用 nextTick

    javascript 复制代码
    //在某个方法中修改了组件的响应式数据,想要立即获取更新后的 DOM 状态
    methods: {
      addItem() {
        this.list.push(newItem);
        // 立即尝试获取列表高度
        console.log(this.$refs.listContainer.offsetHeight); // 可能得到旧的高度
      }
    }
    //解决方案:
    methods: {
      addItem() {
        this.list.push(newItem);
        this.$nextTick(() => {
          // DOM 更新后获取列表高度
          console.log(this.$refs.listContainer.offsetHeight);
        });
      }
    }

四、总结

在生命周期钩子中

  • created :DOM 未生成,无法操作 DOM。
  • mounted :初始 DOM 已渲染,可直接操作 DOM,无需 nextTick
  • beforeUpdate :数据已更新,DOM 未更新,如需操作更新后的 DOM,需使用 nextTick
  • updated :DOM 已更新,可直接操作更新后的 DOM,无需 nextTick

在数据更新的方法中

  • 数据变化后,DOM 更新是异步的
  • 如果需要在数据更新后立即获取更新后的 DOM,需要使用 this.$nextTick
相关推荐
慧一居士14 分钟前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead16 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_7 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
伍哥的传说8 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js