从同步到异步:Vue 3 的异步更新策略与 `tick` 机制

news2025/2/27 5:51:39

1. 引言:Vue 3 的异步更新,我们真的了解吗?

在日常开发中,我们都知道 Vue 3 是异步更新的。大多数时候,我们只是简单地使用 refreactivecomputed 等 API,享受着 Vue 的响应式系统带来的便利。然而,当我们在某些场景,忽略“异步”更新的底层逻辑,就会导致和预期不相符的问题。

最近,我在一个项目中遇到了一个关于 computed 的问题,这让我重新审视了 Vue 3 的异步更新机制。下面,我将分享这段经历,希望能帮助大家更好地理解 Vue 3 的异步更新策略。

2. 问题背景:computed 的二次转换与异步更新的冲突

在项目中,我需要对一个响应式数据进行二次转换,以便在模板中使用。为了分离逻辑,我使用了 computed 来实现这个转换。
整个问题涉及到3个文件:

index.vue
Temp.vue
useSearchParam.ts

在index.vue中,使用Temp.vue模块和useSearchParam。然后在index.vue中,通过computed,来处理和searchParam相关的转换逻辑。
代码大致如下:
index.vue

<template>
  <Temp ref="tempRef" :param="computedParam"/>
</template>
<script setup lang="ts">
...
const { searchParam } = useSearchParam(()=>{
  tempRef.value.load();
});
const computedParam = computed(() => {
  return {
    businessCode: `computed businessCode:${searchParam.businessCode}`
  };
});
</script>

Temp.vue 组件中,我通过 props 接收 computedParam,并在 load 方法中打印 businessCode
Temp.vue

<template>
  <span>{{ param.businessCode }}</span>
</template>
<script lang="ts" setup>
interface Props {
  param: any
}
const props = defineProps<Props>();
const load = () => {
  console.log("temp-load-1", props.param.businessCode);
  ...
};
defineExpose({ load });
</script>

useSearchParam.ts 中,我通过异步加载数据并更新 searchParam
useSeachParam.ts

export function useSearchParam(dataLoaded: Function) {
	const searchParam = reactive({});
	onMounted(async () => {
	  const result = await store.businessNames.load({}));
	  searchParam["businessCode"] = first(result)?.code;
	  dataLoaded && dataLoaded();
	});
}

然而,当 businessNames 加载完成后,temp-load-1 打印出来的 businessCodeundefined,而在span中却正常渲染出来了businessCode的值。这让我感到困惑,为什么没有获取到最新的 computedParamcomputed 值?

3. 问题剖析:computed 的惰性求值与异步更新的冲突

通过分析,我发现问题的根源在于 computed 的惰性求值机制。computed 只有在被访问时才会重新计算,而在异步更新中,computed 不会立即重新计算,导致在同步代码中获取到旧的值。

具体来说,当 searchParam.businessCode 被更新时,Vue 会标记 computedParam 为“脏”状态,但不会立即重新计算。只有在 computedParam 被访问时,Vue 才会重新计算并返回最新的值。然而,dataLoaded是一个同步函数(关键之处),当它触发了Temp里面的load方法时,computedParam 还没有被重新计算,导致 props.param.businessCode 仍然是 undefined

4. 解决方案:使用 nextTick 确保 computed 的更新

为了解决这个问题,我调整了 useSearchParam.ts 中的代码,将 dataLoaded 回调函数放入 nextTick 中执行:

onMounted(async () => {
  const result = (await store.businessNames.load({})) as BusinessNameItem[];
  searchParam["businessCode"] = first(result)?.code;
  nextTick(() => {
    dataLoaded && dataLoaded();
  });
});

通过这种方式,dataLoaded 回调函数会在 Vue 的下一个 tick 中执行,此时 searchParam 的更新已经完成,computedParam 也已经重新计算,并返回了最新的值。因此,temp-load-1 和 里面一样,都显示出来了相同的正常值。

5. 深入理解:Vue 3 的 tick 机制

通过这次问题的解决,我深入理解了 Vue 3 的 tick 机制。tick 是 Vue 完成一次响应式数据更新和 DOM 渲染的过程。Vue 会将所有的响应式数据更新和 DOM 更新批量处理,并在下一个事件循环的 tick 中执行。

nextTick 中,Vue 会完成所有响应式数据的更新和 DOM 的渲染,确保回调函数在最新的状态下执行,具体到这个问题中,computedParam已经完成了更新。因此,通过 nextTick,我们可以确保在异步更新后获取到最新的computedParam的 computed 值。

6. 总结:从同步到异步,理解 Vue 3 的异步更新策略

通过这次经历,我们不仅解决了 computed 的异步更新问题,还深入理解了 Vue 3 的 tick 机制。Vue 3 的异步更新策略虽然复杂,但通过合理使用 nextTick,我们可以确保在异步更新后获取到最新的数据。

在日常开发中,我们应该更加关注 Vue 3 的异步更新策略,尤其是在使用 computedwatch 时,确保数据的更新和渲染顺序正确。通过这种方式,我们可以编写出更加高效和可靠的 Vue 3 代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2306722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024中国信通院“集智”蓝皮书合集(附下载)

【目 录】 1. 数字政府一体化建设蓝皮书&#xff08;2024年&#xff09; 2. 数字乡村发展实践蓝皮书&#xff08;2023年&#xff09; 3. 中国工业互联网发展成效评估报告&#xff08;2024年&#xff09; 4. 云计算蓝皮书&#xff08;2024年&#xff09; 5. 具身智能发展报告…

nvm 1.2.2 报错解决方法 The system cannot find the file specified.

安装了最新版本nvn1.2.2后&#xff0c;安装老版本node时报错&#xff08;安装新版本没问题&#xff09;&#xff0c;报错内容如下&#xff1a; error installing 14.16.0: open C:\Users\admin\AppData\Local\Temp\nvm-npm-430098699\npm-v6.14.11.zip: The system cannot fin…

OpenEuler学习笔记(三十五):搭建代码托管服务器

以下是主流的代码托管软件分类及推荐&#xff0c;涵盖自托管和云端方案&#xff0c;您可根据团队规模、功能需求及资源情况选择&#xff1a; 一、自托管代码托管平台&#xff08;可私有部署&#xff09; 1. GitLab 简介: 功能全面的 DevOps 平台&#xff0c;支持代码托管、C…

平台设备驱动之gpio子系统(写驱动实现在/sys/...目录下用echo命令点灯)

1、 关键函数&#xff08;include/linux 及 driver目录下&#xff09; ​ module_platform_driver(leds_drv); //平台设备驱动入口//获取匹配成功后设备树节点中的 property ​ of_get_named_gpio_flags(node, "led_gpio", 0, &flags); //在/sys/目录下创建文…

JavaScript将:;隔开的字符串转换为json格式。使用正则表达式匹配键值对,并构建对象。多用于解析cssText为style Object对象

// 使用正则表达式匹配键值对&#xff0c;并构建对象 let string2Json(s)>{const r {};s.replace(/&#xff1b;/g, ;).replace(/\;/g, \n).replace(/&#xff1a;/g, :).replace(/\n/g, \n)//合并多个换行符.split(\n).forEach(item > {const [k, v] item.split(:);(k…

2025年追觅科技社招校招入职测评北森题库商业推理测试内容与技巧

在追觅科技的招聘流程中&#xff0c;无论是校园招聘还是社会招聘&#xff0c;应聘者都需要通过北森测评题库的商业推理部分。这部分的测评旨在评估应聘者的商业推理能力&#xff0c;是评估考生综合能力的重要工具。考试时间为40分钟&#xff0c;需要完成28题&#xff0c;题型以…

【工具变量】公司企业数字领导力(2004-2023年)

数据简介&#xff1a;企业数字化领导力是指在数字经济时代&#xff0c;领导者通过战略性地使用数字资产、引领组织变革&#xff0c;使企业在数字化环境中获得持续成功的能力。对于上市公司而言&#xff0c;这种领导力尤为重要&#xff0c;因为它直接关系到企业的战略方向、市场…

【Vue工作原理】VueCli4 模板文件template不存在会生产一个默认文件原理

Vue CLI 4 的 HtmlWebpackPlugin 在模板文件缺失时&#xff0c;‌不会中断构建流程‌&#xff0c;而是自动生成一个‌极简 HTML 结构‌&#xff08;DeepSeek回答&#xff09; ‌&#x1f4d8; 官方资料来源解析&#xff08;基于 2025 年存档数据&#xff09;‌ 当前时间&#…

数据开发的简历及面试

简历 个人信息: 邮箱别写QQ邮箱, 写126邮箱/189邮箱等 学历>>本科及以上写,大专及以下不写 专业>>非计算机专业不写 政治面貌>>党员写, 群众不用写 掌握的技能: 精通 > 熟悉 > 了解 专业工具: 大数据相关的 公司: 如果没有可以写的>>金融服…

如何在docker上部署前端nginx服务(VUE)

目录结构 clean.sh docker stop rszWeb; docker rm rszWeb; start.sh docker run -d \ --name rszWeb \ -p 7084:80 \ -m 500m \ --privileged=true \ --restart=always \ -v /home/rsz/ui/conf/nginx.conf:/etc/nginx/nginx.conf \ -v /home/rsz/ui/logs:/meta/logs \ -v /…

模型和数据集的平台之在Hugging Face上进行模型下载、上传以及创建专属Space

模型下载 步骤&#xff1a; 注册Hugging Face平台 https://huggingface.co/ 新建一个hf_download_josn.py 文件 touch hf_download_josn.py 编写hf_download_josn.py文件 import os from huggingface_hub import hf_hub_download# 指定模型标识符 repo_id "inter…

[Web 信息收集] Web 信息收集 — 手动收集 IP 信息

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] Web 安全攻防 - 学习手册-CSDN博客 0x01&#xff1a;通过 DNS 服务获取域名对应 IP DNS 即域名系统&#xff0c;用于将域名与 IP 地址相互映射&#xff0c;方便用户访问互联网。对于域名到 IP 的转换过程则可以参考下面这篇…

排序算法(3):

这是我们的最后一篇排序算法了&#xff0c;也是我们的初阶数据结构的最后一篇了。 我们来看&#xff0c;我们之前已经讲完了插入排序&#xff0c;选择排序&#xff0c;交换排序&#xff0c;我们还剩下最后一个归并排序&#xff0c;我们今天就讲解归并排序&#xff0c;另外我们还…

TypeScript - 泛型

泛型允许在定义函数、类或接口时&#xff0c;使用类型参数来表示未指定的类型&#xff0c;这些参数在具体使用时&#xff0c;才被指定具体的类型&#xff0c;泛型能让同一段代码适用于多种类型&#xff0c;同时仍然保持类型的安全性。 举例&#xff1a;如下代码中 <T> 就…

Python基于Django和Vue的校园互助平台(附源码、文档说明)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

Redis 高可用性:如何让你的缓存一直在线,稳定运行?

&#x1f3af; 引言&#xff1a;Redis的高可用性为啥这么重要&#xff1f; 在现代高可用系统中&#xff0c;Redis 是一款不可或缺的分布式缓存与数据库系统。无论是提升访问速度&#xff0c;还是实现数据的高效持久化&#xff0c;Redis 都能轻松搞定。可是&#xff0c;当你把 …

【Linux】调试工具GDB的使用及案例讲解

Linux系列 文章目录 Linux系列前言一、gdb的使用背景二、gdb的使用总结 本篇主要针对小白讲解&#xff0c;可以很多地方比较咯嗦 前言 GDB是Linux下一款强大的调试工具。GDB可以调试C、C、Java等语言&#xff0c;对于在Linux下工作的程序员来说&#xff0c;GDB是必不可少的调试…

DeepSeek回答:AI时代Go语言学习路线

最近有小伙伴经常会问&#xff1a;**该如何学习入门Go语言&#xff1f;怎样提升Go语言Coding水平&#xff1f;**这篇文章我们就使用DeepSeek来梳理下Go语言在AI时代的学习路线。 向DeepSeek提问的问题原文&#xff1a; 你现在是一名资深的Go语言工程师&#xff0c;精通Go语言并…

1分钟用DeepSeek编写一个PDF转Word软件

一、引言 如今&#xff0c;在线工具的普及让PDF转Word成为了一个常见需求&#xff0c;常见的pdf转word工具有收费的wps&#xff0c;免费的有pdfgear&#xff0c;见下文&#xff1a; PDFgear:一款免费的PDF编辑、格式转化软件-CSDN博客 还有网上在线的免费pdf转word工具smallp…

【Linux】初探信号的奥秘

目录 一、引入信号&#xff1a; 1、什么是信号&#xff1a; 二、前后台进程&#xff1a; 三、信号的处理方式&#xff1a; 四、键盘数据与信号&#xff1a; 前言&#xff1a; 在Linux系统编程中&#xff0c;信号&#xff08;Signal&#xff09;是一种至关重要的进程间通信…