【vue其他相关】欢迎讨论!异步请求放在生命周期中的created还是mounted,已填坑

2023-11-16

前言

曾经在百度上搜这个问题,看到的答案都是相互复制粘贴的,而且个人觉得并没具体场景举例说明,并没有好的答案。于是自己立贴,留下这个坑,等日后遇到了一些场景,就把分析写在这里,把这个问题搞明白。

经过一些网友的评论提醒,发现之前写的结论还是过于草率,本人也会不断的更新完善。感谢。

前置知识点:

  • 事件循环机制
  • 子父组件的生命周期执行顺序

这两个知识点最好要有所了解,这样下面能够更好的了解原理。


两个生命周期

created:data属性,methods属性,watch监听等都初始化好了,也就是可以使用了。

mounted:已经把内存中编译好的模板替换到页面中,也就是视图层已渲染成最新的,vue 实例完全创建完毕。可以操作DOM。理论上内部的子组件也执行完了mounted。


场景1

之前看到网上最多复制粘贴的是:

建议放在created里,如果在mounted钩子函数中请求数据可能导致页面闪屏问题。其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了。

下面有网友说了闪屏是什么意思,就是在请求没回来之前,页面已经挂载好了,显示的是data里的原始数据(或者空数据),当请求回来后替换掉data的内容,就会有个内容切换的情况出现,也就是闪屏。

但上面说的放在created不是解决这个问题的关键,因为异步请求是异步执行,vue会先将created和mounted里的同步代码先执行完,才会开启下一轮的事件循环去执行这俩钩子里异步请求的方法。

口说无凭,上代码:

<div v-for="i in 20000" :key="i"> // 循环2w张图,为了让mounted晚执行
  <img src="../public/test.png" alt="" srcset="" />
</div>
created() {
 this.getData(
    " https://mock.mengxuegu.com/mock/625bfd5d66abf914b1f1bf07/example/proxy"
  );
  console.log("created执行", new Date());
},
mounted() {
  console.log("mounted执行", new Date());
},
methods: {
  getData(url) {
    fetch(url).then(
      (response) => {
        //处理http响应
        console.log("请求到数据", new Date());
      },
      (error) => {
        //处理错误
        console.log("请求到数据", error);
      }
    );
  },
},

运行后看看打印台:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

咱们可以看到,created是在18秒的时候执行的,mounted是在20秒执行的,咱们这个异步请求也是在20秒发送,获取到数据的时间是0.1秒。如果按照网上的说法,那么应该是created打印完,0.1秒后请求的结果打印,最后不到2秒后mounted打印。但事实是异步请求在mounted之后。

所以,不存在说异步请求放在created里会比mounted触发早一点的情况,此时的异步请求无论放在哪个钩子里,都是会在mounted之后执行。

这里还有一个补充,假如有ab两个请求一前一后相继触发,b是1秒后拿到数据,a是3秒后拿到数据,b的then会先执行。

场景2

这个也是网上复制粘贴比较多的。

如果把所有请求放在created里面的话,请求过多会,加载太慢会导致页面出现短暂的白屏情况,一般上我写的话,接口不复杂会放created里面,接口多复杂的话会放在mounted里面。

其实这个描述已经有点接近意思了,我们用一个拥有子组件的父组件来举例子,然后来分两种情况去看。

第一种

该父组件内的子组件不需要在内部钩子中调用接口请求。那么就会和场景一一样,父组件先执行完mounted的同步代码后,才去调用异步请求,此时组件已挂载完毕。多少个异步请求放在哪个钩子都一样,都是会加载完子组件后才去请求。

所以一定会先白屏,放哪都一样。

第二种

该父组件内部有一个子组件在钩子中调了接口请求。我们知道理论上,父组件在执行完beforeMounted后就会去启动子组件的生命周期,子组件执行完mounted之后,父组件才会执行自己的mounted。

当我们在父组件中把异步请求放在created中时:

父:

created() {
  this.getData(
    " https://mock.mengxuegu.com/mock/625bfd5d66abf914b1f1bf07/example/proxy"
  );
  console.log("created执行", new Date());
},
mounted() {
  console.log("mounted执行", new Date());
},
methods: {
  getData(url) {
    fetch(url).then(
      (response) => {
        //处理http响应
        console.log("父请求到数据" + url, new Date());
      },
      (error) => {
        //处理错误
        console.log("请求到数据", error);
      }
    );
  },
},

子:

mounted() {
  this.getData(
    " https://mock.mengxuegu.com/mock/625bfd5d66abf914b1f1bf07/example/query"
  );
  console.log("子mounted执行", new Date());
},
methods: {
  getData(url) {
    fetch(url).then(
      (response) => {
        //处理http响应
        console.log("子请求到数据", new Date());
      },
      (error) => {
        //处理错误
        console.log("子请求到数据", error);
      }
    );
  },
},

此时执行,在控制台能看到两种情况:
在这里插入图片描述
在这里插入图片描述
能看到父子谁先拿到数据谁就打印,但接口的触发顺序应该是子先。

好,接下来让父级渲染2w张图,结果又是这样:

在这里插入图片描述
在这里插入图片描述

明明子的数据先拿到,但却先打印父的数据,且把20w张图换到子组件去渲染也是一样的情况。

原因我还不太明确,但是是不是可以说当页面渲染稍微多点时,把异步请求放在created中时,父总是会先触发then呢,无论子多快拿到数据。

ok,我们这回把父的异步请求放进mounted中执行,当子组件渲染2w张图和当父组件渲染2w张图的结果都类似以下的例子:

在这里插入图片描述
在这里插入图片描述
原因我还不太明确,但是是不是可以说当页面渲染稍微多点时,把异步请求放在mounted中时,子总是会先触发then呢,无论父多快拿到数据。

欢迎讨论!


场景3

本人亲自遇到,不过和异步没有多大关系,但和生命周期有关,就先记录在这里吧。使用elementUI时,有些组件如果在mounted中直接赋值,组件已经渲染过一次,添加数据后组件是不会更显示的。放在created里就可以。


结论

如果是单单的一个父级组件,放哪里都无所谓。

但是如果涉及到了要控制子父组件先后显示正确内容的时候,就可以考虑下父组件的请求要放在哪个钩子里了。想要子组件先拿到数据渲染就放在mounted中,想要父组件先拿到数据就放在created中。

没想到直接颠覆了我之前的结论,笑死


如何处理场景一和场景二的问题

其实都是同一个问题,白屏怎么办?

在没有拿到接口数据的时候如何显示页面,以及拿到数据后如何做体验比较友好的内容切换。

其实网上的解决方案有很多,我这里就抛砖引玉一下,例如第三方UI库的骨架屏组件,数据没来之前,显示骨架屏,数据到了做个切换体验会好些;又例如数据没来之前搞个全局的loading样式,数据来了显示并取消loading等。


最后

这里给新人再加个提示。

如果拿到的数据是通过标签注入渲染显示的,最好搞个外标签判断一下是否有值再去渲染,怕dom已经开始渲染但数据还没拿到,有些组件会直接报错。

<div v-if="dataList.length > 0">
   // 防止内部模板报错
</div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【vue其他相关】欢迎讨论!异步请求放在生命周期中的created还是mounted,已填坑 的相关文章

  • nuxtjs 无法在生产环境中显示动态 url

    我正在使用 nuxjs 构建我的项目 并创建一个动态显示地点信息的页面 当我跑步时npm run dev并测试http localhost 3000 place 66bb50b7a5 http localhost 3000 place 66
  • Laravel Vue js spa 应用程序

    1 我想知道为什么人们使用两台服务器用 laravel 制作 vuejs SPA 我想我们可以用另一种方式 制定这样的路线 Route get any function return view index gt where any 并让 v
  • 我正在尝试向我的 vue.js 项目添加背景图像

    我想添加覆盖整个页面的背景图像 然而现在看起来是这样的 我希望它跨越整个网页 在 vue js 中这将如何完成 我还想要一个动画工具栏 以便当页面不滚动时工具栏是透明的并呈现背景图像的外观 当它滚动时 工具栏将具有当前的蓝色 这是我的小提琴
  • 有没有办法使用 Vue-Router 从动态 URL 中删除目录?

    我为一家保险经纪公司构建了一个 vue js Web 应用程序 其中每个代理人都有自己的网站 该网站是根据他们的个人资料生成的 这就是我的 vue router 索引文件中的链接的样子 path agents id name AgentSi
  • 在 Angular 中使用 Vue 组件

    我有一个用 Vue 构建的项目 我想在 Angular 应用程序中重用 Vue 应用程序中的组件 这样我就不必从头开始重建每个组件 我在medium上看到了这个教程 如何在 Angular 应用程序中使用 Vue 2 0 组件 https
  • 监听来自动态vue组件的事件

    您将如何侦听动态创建的组件实例发出的事件 在示例中 顶部组件添加到 DOM 中 而第二个组件是在 javascript 中动态创建的 Vue component button counter data function return cou
  • Vue.js - 以编程方式设置槽内容

    有什么办法可以从组件内部设置 覆盖插槽的内容吗 喜欢 模板 div div
  • vue-chartjs 反应数据错误

    我正在尝试使用反应式数据混合vue chartjs http vue chartjs org home id reactive data 用于设置初始数据的已安装函数正在运行 我可以使用 API 响应正确查看图表 fetchSessionT
  • 如何从vuejs和firestore获取文档的id?

    我有这个代码可以从 firestore 获取所有文档 const getThemesList async commit gt const snapshot await firebase firestore collection themes
  • 将 Stripe.js 作为 ES 模块导入到 Vue 中

    我正在尝试按照 stripe elements 文档中的说明并将 ES 模块安装到我的 Vue 支付组件中 https stripe com docs stripe js html js 请注意 目前 Stripe 网站 ES 模块安装选项
  • vue如何设置嵌套对象的默认道具

    我的道具是这样的 house kitchen sink 我尝试过类似的事情 但没有成功 props house type Object default gt kitchen sink 如何为此类对象设置默认道具 来自文档 对象或数组默认值必
  • nuxt中根据url参数动态加载组件

    我在 nuxt 中有一个页面 分为两部分 第一部分是一个普通的模板结构 填充了基于 url 参数的动态内容 第二部分是应根据此数据加载的组件 我正在尝试这样完成它
  • 在Vue.js 3中添加全局变量

    如何在 Vue js 3 中添加全局变量 在 Vue js 2 中 我们在main js file Vue prototype myGlobalVariable globalVariable 最直接的替换就是app config globa
  • 如何使用 vue 观察对象数组中的特定属性

    我正在使用 vue js 2 5 2 我有一个对象数组 我想观察 forms selected 如果它发生变化 则调用一个函数 这是我的尝试 但显然这是不正确的 我尝试将数组放入 for 循环中以观察所选的每个对象的属性 watch for
  • 实现npm包自定义组件VueJS

    我正在尝试使用以下 npm package 来绕过 X frame 选项 https www npmjs com package x frame bypass https www npmjs com package x frame bypa
  • 如何在 NuxtJs 路由中使用 *(星号)?

    在 vue cli 生成的普通 Vue 不是 Nuxt 项目中 使用 在 vue router 中这样工作 export default new Router routes path about name about component A
  • beforeRouteUpdate 和观看 '$route' - Vue.js 之间的区别?

    正如我们所知 为了对我们使用的同一组件中的参数变化做出反应beforeRouteUpdate挂钩或观看 route 观看 route const User template watch route to from react to rout
  • 在 vuejs 上将 \n 替换为新行

    我正在尝试将 n 字符替换为来自端点的数据的新行 I tried p item licensedocument legal documentText replace r n r n g br p 并没有奏效 当我将replace 写入问题末
  • Vue: vue-i18n: 无法翻译 keypath 的值,使用 keypath 的值作为默认值

    我正在使用 Vue 我想展示三种语言 英语 他加禄语和宿务语 现在我有错误 无法转换键路径 NavbarMobile home 的值 使用 keypath 的值作为默认值 我通过 console log this i18n locale 检
  • 将变量从调用它的父页面传递给 Vue 组件

    我有一个简单的表格 显示了我的所有数据 主文件 php table class table table bordered table hover thead tr th Job Name th th Job Description th t

随机推荐

  • 单片机毕业设计 RFID智能门禁系统

    文章目录 1 简介 2 绪论 2 1 课题背景与目的 3 射频识别 3 1 射频识别技术 3 2 射频识别模块 3 2 1 RFID模块 3 2 2 RFID模块组成 4 系统设计 4 1 系统架构 4 1 1 硬件部分 4 1 2 软件部
  • 使用 git 提交到指定远程分支

    使用 git 提交到指定远程分支 git add git commit 或者使用 git commit m messges git pull origin 远程分支名 相当于指定分支的代码与当前分支的代码合并到了一起 git push or
  • 1分钟部署一个属于自己的网站,借助云开发静态网站部署属于自己的网站

    今天来教大家部署一个属于自己的第一个静态网站 因为这里借助小程序云开发的静态服务器资源 所以可以轻松的实现自己网站的部署 部署完以后可以在电脑浏览器 手机浏览器 微信公众号里面展示 老规矩 先看效果图 简单起见 我这里写一个最简单的html
  • IEEE 802.3以太网帧封装

    要求 1 要求画出界面 以太网帧的数据部分 源MAC地址和目的MAC地址均从界面输入 2 计算后的校验和字段和封装后的结果可以从界面上输出 3 生成多项式G X X8 X2 X1 1 或者生成多项式G X X32 X26 X23 X22 X
  • SpringBoot-基础篇复习(全)

    本文包含SpringBoot基础篇的所有知识点 大家一起来学习吧 开启一段新的旅程 加油吧 springboot是由Picotal团队提供的全新框架 用来简化spring的搭建和开发过程的配置 因为spring的配置比较繁琐 故引入了spr
  • 不吐不快:程序员到底有没有前途(一位前辈写的)

    早上到单位 看昨天晚上QQ群里的内容 有人在问做程序员怎么样 马上就有人跳出来告诉他程序员又苦 又累 要求又高 赚得也不比人多 而且30岁以后肯定失业那一套 对程序员的前途 自己有自己的想法 但这没什么好说的 而且每个人都有适合本人的路 也
  • ceph分布式存储-常见MON故障处理

    1 常见 MON 故障处理 Monitor 维护着 Ceph 集群的信息 如果 Monitor 无法正常提供服务 那整个 Ceph 集群就不可访问 一般来说 在实际运行中 Ceph Monitor的个数是 2n 1 n gt 0 个 在线上
  • [转]边界值法中的上点、内点和离点的定义

    上点 是指边界上的点 无论此时的域是开区间还是闭区间 开区间的话 上点就是在域外 闭区间的话 上点就是在域内 离点 是指离上点最近的点 这里就跟是闭区间还是开区间就有关系了 如果是开区间 那么离点就在域内 如果是闭区间 那么离点就在域外 内
  • TCP的keep-alive机制分析

    TCP中的keep alive机制 问题和解决思路 详细内容 缺陷分析 问题和解决思路 建立tcp连接后 双方互相发送信息 但是可能存在的情况是双方在处理数据 暂时并不会互相发送数据 那么这个时候如何判断双方连接是否依然正常 而没有意外断开
  • Python Using EXE

    OS This method has its disadvantage if we want to stop this process We need do it by ourselves except seize the terminal
  • 启动nacos时出现“nacos is starting with cluster”问题

    使用startup cmd命令启动是以集群方式启动nacos 可以看见命令行中有 nacos is starting with cluster 我们可以以单机方式启动nacos 执行以下命令 startup cmd m standalone
  • MySql导入导出数据库(含远程导入导出)

    一 导入导出本地数据库 导出 1 先运行cmd cd 到mysql安装目录中的bin文件夹 2 mysqldump u root p 数据库名 gt 导出文件名 sql 其他情况下 1 导出整个数据库 mysqldump u 用户名 p 数
  • 2023华为od机试 Java 实现【德州扑克】

    前言 本题使用Java解答 如果需要Python代码 请参考以下链接 链接 题目 我们可以选择五张牌 它们的范围是 每张牌的大小在2 10之间 或者字母J Q K A 牌花色为红桃 黑桃 梅花 方块四种花色之一 现在一共有6种牌型 牌型1
  • 最新的ARM-GCC下载安装指南

    GCC下载网址 https developer arm com tools and software open source software developer tools gnu toolchain gnu a downloads 我使
  • 搭建一个属于自己的个人网站怎样选择服务器

    不管是想搭建一个属于自己的个人网站 还是想开发一个企业项目上云 都必须拥有一台云服务器 云服务器是公有云的支柱之一 我用过很多大厂的云服务器 还记得读研期间我刚开始入门的时候 自己尝试搭建了一台云服务器建网站 后来在一个导师项目中刚好需要用
  • 双指针笔记

    双指针是在一次for循环中使用两个指针完成需要两个for循环的工作 其主要有两种方法 快慢双指针 从一端开始 设置两个速度不一样的指针进行遍历 public int removeElement int nums int val int fa
  • 关于C++中void*形参兼容问题,血的教训!

    关于C 中void 形参兼容问题 血的教训 C语言中void 作为形参的用法 C 中void 作为形参的用法 C语言中void 作为形参的用法 最近在实操一本算法书上的代码的时候 碰到了形如int comp void void 这样的形参列
  • 一种通用代码模型的构建与实现

    开发思路 总体开发思路 代码解析 需要考虑的问题是 目前已经实现了70 左右的功能 代码片段的内在结构 识别代码片段中所存在的对象元素 系统根据不同的对象元素的分类能快速执行相应的处理程序 将处理的结果进行传递 将处理过程进行缓存 保留代码
  • 程设课终章:c++使用socket实现bmp图片的传输

    特别鸣谢 44条消息 C UDP发送接收文件 BMP 我不在你不在的博客 CSDN博客 里面一些概念 ip地址 电脑门牌号 端口号 做这件事的行动代号 协议 接收方和发送方都必须遵守的一种规则 socket是基于tcp ip协议发送数据技术
  • 【vue其他相关】欢迎讨论!异步请求放在生命周期中的created还是mounted,已填坑

    文章目录 前言 两个生命周期 场景1 场景2 场景3 结论 如何处理场景一和场景二的问题 最后 前言 曾经在百度上搜这个问题 看到的答案都是相互复制粘贴的 而且个人觉得并没具体场景举例说明 并没有好的答案 于是自己立贴 留下这个坑 等日后遇