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
相关推荐
careybobo1 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)1 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之2 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端3 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡3 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木4 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!4 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
難釋懷5 小时前
JavaScript基础-移动端常见特效
开发语言·前端·javascript
还是鼠鼠5 小时前
Node.js全局生效的中间件
javascript·vscode·中间件·node.js·json·express
自动花钱机5 小时前
WebUI问题总结
前端·javascript·bootstrap·css3·html5