【vue其他相关】欢迎讨论!异步请求放在生命周期中的created还是mounted,已填坑
文章目录
- 前言
- 两个生命周期
- 场景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,已填坑相关推荐
- Vue生命周期中的created和mounted的区别
之前大部分时候都是用angular开发项目,vue写的很少,最近有必要把vue和webpack重新整理一下了.下面我们先看一下Vue生命周期中的created和mounted的区别. 我们先看一张图( ...
- Vue生命周期中对mounted、beforeUpdate、updated的理解
Vue生命周期中对mounted.beforeUpdate.updated的理解 前言 mounted.beforeUpdate.updated 前言 以下文章纯为个人理解,如有错误,请求评论区指正呀 ...
- Vue生命周期中mounted、created、methods、computed、watched等的区别
1.Vue生命周期中mounted和created的区别 https://blog.csdn.net/xdnloveme/article/details/78035065. 2.[Vue] 生命周期, ...
- vue中在哪个生命周期中dom被渲染_vue请求数据放在哪个生命周期?
泻药! 玩vue.或者react或者其他任何mvvm库,很重要的一点是要弄清楚生命周期(不要太重要). 比如拿vue来说,每个生命周期提供的钩子函数,其实对应的是一个完整的vue实例(对象)诞生的过程 ...
- Vue 生命周期中 mounted( ) 和 created( ) 的区别
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 一.什么是生命周期? 用通俗的语言来说,就是Vue中实例或者组件从创建到消灭中间经过的一系列过程.虽 ...
- Vue生命周期中mounted和created的区别
一.什么是生命周期? 用通俗的语言来说,就是Vue中实例或者组件从创建到消灭中间经过的一系列过程.虽然不太严谨,但是也基本上可以理解. 通过一系列实践,现在把所有遇到的问题整理一遍,今天记录一下cre ...
- 接口请求一般放在哪个生命周期中?
接口请求一般放在 mounted 中,但需要注意的是服务端渲染时不支持 mounted,需要放到 created 中. 本文转载于Boss直聘 陈大鱼头
- vue生命周期中,钩子函数执行顺序
1. 流程图 2.一般的执行顺序(从上往下): beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用. created ...
- 7、Vue实例的生命周期钩子(created、mounted、updated、destoryed)
1.Vue实例 new Vue()创建一个Vue实例 所有的组件其实都是Vue实例 2.Vue实例的生命周期钩子 每个Vue实例在被创建时都要经过一系列的初始化过程 初始化过程 created() 组 ...
最新文章
- 独家 | 初学者的问题:在神经网络中应使用多少隐藏层/神经元?(附实例)
- 上海交大计算机学院张卫东,张卫东
- 【原创】一个亿级数据库优化过程
- Talos实验室深入我国DDoS黑市DuTe 揭露各种DDoS团伙、平台、工具及攻击
- Python 进阶 —— 重访 tuple
- 2013年吴超的个人总结
- 剑指 只出现一次的数字
- kuangbin RMQ
- abbot_release
- pdf factory pro7序列号教你如何打印转换PDF教程
- vs2010中svn使用教程_VS2010中使用ankhSVN
- TP框架和Laravel框架的区别
- 【Hexo搭建个人博客】:yilia主题配置(二) - 背景图片
- 郭盛华动真格了!新公司获百亿融资,网友:还招人不
- 批量删除微博(不能翻页)
- 遍历目录 nftw and ftw
- 有一个人有一百块钱, 打算买一百只鸡, 现在大鸡三块钱一只, 小鸡一块钱三只, 不大不小的鸡两块钱一只. Java编程实现,刚好用一百块钱买一百只鸡.
- 计算向量相似度 ---余弦相似度
- muse-ui.css_Muse UI:适用于Vuejs 2.0的Material Design UI库
- RabbitMQ 从入门到精通 消息应答 持久化 交换机 队列 发布确认 集群 等