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
相关推荐
栈老师不回家3 分钟前
axios 二次封装及 api 解耦【Vue】
前端·javascript·vue.js
多多*7 分钟前
Vue.js 插槽 Slots 实际应用 最近重构项目的时候遇到的...
前端·vue.js·重构
俊俊谢44 分钟前
Admin.NET框架前端由于keep-alive设置缓存导致的onUnmount未触发问题
前端·缓存·.net
hibiscusxin1 小时前
vue-office:word(.docx)、pdf、excel(.xlsx,.xls)格式文件预览
vue.js·word·excel
老魏爱学习1 小时前
记一次JS逆向-新榜数据nonce和xyz参数分析
开发语言·javascript·笔记·网络安全·php
Rverdoser1 小时前
Day10_CSS过度动画
前端·css
鲤鱼_5992 小时前
记录———封装uni-app+vant(u-upload)上传图片组件
vue.js
joe02352 小时前
Vue+ElementUI 导出为PDF文件
vue.js·elementui·pdf
Jornici3 小时前
搭建vue-electron项目
前端·vue.js·electron
三天不学习3 小时前
前端开发之 节流与防抖
前端·javascript·节流防抖