vue:对三种获取更新后的dom的方式进行分析

一、问题分析

由于vue的异步更新机制,我们在同步代码中是无法获取到更新后的dom的信息的

针对这个问题,我们有三种解决方案获取更新后的dom:

1.nextTick()

2.setTimeout()

3.在微任务中获取

因为更新是在同步任务结束后,执行微任务之前,所以上面三种方式可以得到更新后的dom。

二、执行顺序分析

先看代码,下面的代码中,通过点击使得绑定的按钮元素高度增加,在js中通过打印来去观察不同获取该元素信息的方式的区别。

<template>
  <div class="page">
    <button
      @click="clickButton"
      ref="buttonRef"
      :style="{ height: `${height}px`, width: '60px' }"
    ></button>
    <div class="info">{{ height }}</div>
  </div>
</template>
<script setup lang="ts">
import { nextTick, ref } from "vue";
const height = ref(40);
const buttonRef = ref();
const clickButton = async () => {
  height.value = height.value + 10;
  console.log(buttonRef.value.style.height, "直接打印"); // 40px
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout0打印1"); // 50px
  }, 0);
  await console.log("dom已更新");
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout0打印2"); // 50px
  }, 0);
  setTimeout(() => {
    console.log(buttonRef.value.style.height, "setTimeout100打印"); // 50px
  }, 100);
  nextTick(() => {
    console.log(buttonRef.value.style.height, "nextTick打印"); // 50px
  });
  console.log("测试数据");
  console.log(buttonRef.value.style.height, "微任务打印"); // 50px
};
</script>
<style>
.page {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
</style>

我们可以观察到,除了在同步代码中获取按钮元素的信息,都得到了更新后的按钮高度。同时我们可以发现,nextTick中的任务是在微任务队列的末尾的,如果把这段代码提前到同步任务中也是同样的效果。

由此,我们可以得出结论,获取更新后dom的速度,微任务中获取>nextTick中获取>其它延时任务队列中获取

三、为什么nextTick让任务进入微任务队列末尾而不是开头或者中间

1.避免无限循环。如果 nextTick 的回调被添加到队列的开头,那么在执行回调的过程中再次调用 nextTick 可能会导致无限循环,因为新产生的 nextTick 任务会立即执行,从而可能不断地往队列中添加新的任务。

2.性能优化。vue的异步更新是为了让同一个Tick中的数据变化完了再更新,将任务放入末尾也是同样的目的,可以尽可能减少不必要的dom操作。

3.便于调试。如果这个任务会到处都是那么数据的变化是难以预测的。

四、为什么优先使用nextTick()

1.nextTick的作用就是告诉vue这个dom更新好了,简单,稳定,可靠,语义强。

2.方便调试,避免无限循环,性能优化。

3.不用像settimeout一样把任务拖到下一个宏任务。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 很高兴回答你的问题。作为一个 AI 语言模型,我没有实际的经验来记录日记。但是,我可以告诉你,Vue 是一个流行的 JavaScript 框架,它可以帮助开发人员构建交互式的 Web 应用程序。Vue 具有简单易学、灵活性强、性能优异等优点,因此在开发得到了广泛的应用。如果你有任何关于 Vue 开发的具体问题,我很乐意帮助你解答。 ### 回答2: 第一天: 今天开始了一周的vue开发。首先,我花了一些时间了解了一下vue的基本概念和语法规则。我了解到vue是一个渐进式的JavaScript框架,它可以用于构建用户界面。我通过阅读官方文档和参考一些教程来学习如何使用vue。初步了解了vue的组件化开发和数据绑定的概念。 第二天: 今天,我决定尝试一下使用vue来构建一个简单的ToDo列表应用程序。我创建了一个vue项目,并在主组件定义了一些数据和方法。然后,我使用v-for指令来遍历数据,并使用v-bind指令实现了数据的双向绑定。我还添加了一些样式来美化界面。整个过程相对顺利,虽然在处理一些细节时遇到了一些问题,但最终成功完成了ToDo列表应用。 第三天: 今天我决定学习一下vue的路由功能。我在项目引入了vue-router,并创建了一些路由组件。然后我定义了一些路由规则,并在主组件使用<router-view>显示当前路由对应的组件。我还添加了一些导航链接,并用router-link指令实现了路由的切换。学习路由功能过程遇到了一些语法和配置问题,但最终解决了。 第四天: 今天我开始学习vue的状态管理功能。我在项目引入了vuex,并创建了一些状态和mutations。然后我在主组件使用mapState和mapMutations辅助函数来访问和修改状态。学习状态管理的过程,我发现了vuex的一些特性,比如模块化和插件化,并尝试使用这些特性来简化代码结构。 第五天: 今天我专注于学习vue的动画功能。我在项目引入了vue的动画模块,并尝试了一些基本的动画效果,如淡入淡出和滑动效果。我还了解到了过渡和动态组件的概念,并尝试通过vue的transition和transition-group组件实现了这些效果。学习动画功能让我的应用程序变得更加生动和有趣。 第六天: 今天我决定学习vue的性能优化技巧。我通过懒加载和按需加载等技术来优化我的应用程序的加载速度。我还使用vue-devtools工具来分析和优化组件的性能。学习性能优化的过程,我了解到了一些常见的优化策略,如减少不必要的重新渲染和合理使用计算属性等。 第七天: 今天是我这一周的vue开发的最后一天。我回顾了一下这一周的学习和实践,发现自己在vue的开发有了很大的进步。我对vue的基本概念和语法有了更深入的了解,也掌握了一些高级功能和优化技巧。我觉得通过这一周的实践,我对vue的开发有了更加扎实的基础,以后可以更好地应用它来构建复杂的应用程序。 ### 回答3: 第一天: 今天开始进行vue开发,首先安装了vue-cli脚手架工具,并创建了一个新的vue项目。然后我使用vue-router插件来搭建了项目的路由系统,可以通过不同的URL来实现页面的跳转。接下来,我创建了几个组件,包括Header、Footer和Home等,并在页面引入和使用了这些组件。通过组件化的开发方式,我可以更好地管理和复用代码。 第二天: 今天我继续进行vue开发,学习了vue的数据绑定和事件绑定。我在组件创建了一些数据属性,然后在模板使用双花括号语法将数据和页面进行绑定。并且,我还通过v-on指令绑定了一些事件处理函数,实现了一些交互功能,比如点击按钮触发弹窗等。vue的数据驱动模型让我对整个开发过程更加流畅和高效。 第三天: 今天我开始研究vue的组件通信问题。我学习了父子组件之间的通信方式,包括props和$emit方法,可以实现父组件向子组件传递数据和子组件向父组件发送事件。我还学习了兄弟组件之间的通信方式,可以使用事件总线或者vuex来实现不同组件之间的数据传递和状态管理。掌握了这些通信方式后,我能够更好地组织和管理组件之间的关系。 第四天: 今天我学习了vue的生命周期钩子函数。通过对生命周期的理解,我可以在不同阶段进行一些初始化或者清理工作。其,created和mounted是最常用的两个钩子函数,分别在实例创建之后和实例挂载到页面之后被调用。我可以在这两个钩子函数进行一些异步数据请求或者DOM操作,确保在渲染之前或之后进行必要的操作。 第五天: 今天我开始学习vue的状态管理模式vuex。在复杂的应用,组件之间的状态管理变得非常重要,而vuex提供了一个集式的存储管理方案。我创建了一个vuex的store,包括state、mutations、actions和getters等。通过mutations和actions,我可以对state进行修改,并且可以通过getters获取state的数据。vuex的使用大大简化了整个应用的状态管理流程。 第六天: 今天我继续进行vue开发,学习了异步组件和动态路由的使用。在项目,如果有一些组件比较大或者需要懒加载,可以使用异步组件的方式按需加载。我使用了import函数和webpack的代码分割功能来实现异步组件的加载。另外,动态路由可以使得路由的配置更加灵活,可以根据需要动态添加或删除路由配置。这样我可以更好地管理和控制路由。 第七天: 今天是我进行vue开发的最后一天,我进行了项目的打包和部署。通过vue-cli提供的命令,我将项目进行了打包,生成了静态资源文件。然后,我将这些静态资源文件上传到服务器,并配置了nginx代理,使得项目可以通过域名访问。最后,我进行了一些简单的测试和优化,确保项目在生产环境下正常运行。整个vue开发流程结束,我对vue的开发有了更深入的了解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值