文章目录

  • 前言
  • 两个生命周期
  • 场景1
  • 场景2
  • 场景3
  • 结论
  • 如何处理场景一和场景二的问题
  • 最后

前言

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

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

前置知识点:

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

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


两个生命周期

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的同步代码后,才去调用异步请求,此时组件已挂载完毕。多少个异步请求放在哪个钩子都一样,都是会加载完子组件后才去请求。

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

第二种

该父组件内部有一个子组件在钩子中调了接口请求。我们知道理论上,父组件在执行完beforeCreate后就会去启动子组件的生命周期,子组件执行完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>

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

  1. Vue生命周期中的created和mounted的区别

    之前大部分时候都是用angular开发项目,vue写的很少,最近有必要把vue和webpack重新整理一下了.下面我们先看一下Vue生命周期中的created和mounted的区别. 我们先看一张图( ...

  2. Vue生命周期中对mounted、beforeUpdate、updated的理解

    Vue生命周期中对mounted.beforeUpdate.updated的理解 前言 mounted.beforeUpdate.updated 前言 以下文章纯为个人理解,如有错误,请求评论区指正呀 ...

  3. Vue生命周期中mounted、created、methods、computed、watched等的区别

    1.Vue生命周期中mounted和created的区别 https://blog.csdn.net/xdnloveme/article/details/78035065. 2.[Vue] 生命周期, ...

  4. vue中在哪个生命周期中dom被渲染_vue请求数据放在哪个生命周期?

    泻药! 玩vue.或者react或者其他任何mvvm库,很重要的一点是要弄清楚生命周期(不要太重要). 比如拿vue来说,每个生命周期提供的钩子函数,其实对应的是一个完整的vue实例(对象)诞生的过程 ...

  5. Vue 生命周期中 mounted( ) 和 created( ) 的区别

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 一.什么是生命周期? 用通俗的语言来说,就是Vue中实例或者组件从创建到消灭中间经过的一系列过程.虽 ...

  6. Vue生命周期中mounted和created的区别

    一.什么是生命周期? 用通俗的语言来说,就是Vue中实例或者组件从创建到消灭中间经过的一系列过程.虽然不太严谨,但是也基本上可以理解. 通过一系列实践,现在把所有遇到的问题整理一遍,今天记录一下cre ...

  7. 接口请求一般放在哪个生命周期中?

    接口请求一般放在 mounted 中,但需要注意的是服务端渲染时不支持 mounted,需要放到 created 中. 本文转载于Boss直聘 陈大鱼头

  8. vue生命周期中,钩子函数执行顺序

    1. 流程图 2.一般的执行顺序(从上往下): beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用. created ...

  9. 7、Vue实例的生命周期钩子(created、mounted、updated、destoryed)

    1.Vue实例 new Vue()创建一个Vue实例 所有的组件其实都是Vue实例 2.Vue实例的生命周期钩子 每个Vue实例在被创建时都要经过一系列的初始化过程 初始化过程 created() 组 ...

最新文章

  1. 独家 | 初学者的问题:在神经网络中应使用多少隐藏层/神经元?(附实例)
  2. 上海交大计算机学院张卫东,张卫东
  3. 【原创】一个亿级数据库优化过程
  4. Talos实验室深入我国DDoS黑市DuTe 揭露各种DDoS团伙、平台、工具及攻击
  5. Python 进阶 —— 重访 tuple
  6. 2013年吴超的个人总结
  7. 剑指 只出现一次的数字
  8. kuangbin RMQ
  9. abbot_release
  10. pdf factory pro7序列号教你如何打印转换PDF教程
  11. vs2010中svn使用教程_VS2010中使用ankhSVN
  12. TP框架和Laravel框架的区别
  13. 【Hexo搭建个人博客】:yilia主题配置(二) - 背景图片
  14. 郭盛华动真格了!新公司获百亿融资,网友:还招人不
  15. 批量删除微博(不能翻页)
  16. 遍历目录 nftw and ftw
  17. 有一个人有一百块钱, 打算买一百只鸡, 现在大鸡三块钱一只, 小鸡一块钱三只, 不大不小的鸡两块钱一只. Java编程实现,刚好用一百块钱买一百只鸡.
  18. 计算向量相似度 ---余弦相似度
  19. muse-ui.css_Muse UI:适用于Vuejs 2.0的Material Design UI库
  20. RabbitMQ 从入门到精通 消息应答 持久化 交换机 队列 发布确认 集群 等

热门文章

  1. Educational Codeforces Round 81 (Rated for Div. 2)
  2. 老板,我们的网站又挂了——漫谈 DDoS 攻击
  3. 使用Scratch制作打弹球游戏(五)-排名
  4. mockito的用法
  5. 系统接口对接:(1)
  6. 快速排序 php内存超限,数据结构与算法设计
  7. Flink 1.10 版本之前如何生成 Watermark
  8. 谷歌基情录:TensorFlow、Hadoop、MapReduce 都靠他们诞生!
  9. 一个屌丝程序员的青春(三九六)
  10. N4 新标日初级下 问法总结和课后练习题12答案