估计是老问题了, vue 在组件中 created 里用 ajax 或者 axios 请求数据,但是数据在 mounted 前没返回

2021-11-08 16:46:10 +08:00
 elboble
render 页面控制台上会出错,怎么处理?

改成 async: false ,不太优雅。看别人页面上转圈圈,直到数据返回,这个怎么实现的。
2477 次点击
所在节点    Vue.js
24 条回复
liuidetmks
2021-11-08 17:01:13 +08:00
不是应该加一个 loading 状态吗
silk
2021-11-08 17:03:50 +08:00
???????????????????
多看书 多思考
M003
2021-11-08 17:05:47 +08:00
兄弟,你想法错了。
我是封装 axios 中请求前,将该请求丢到一个数组当中。然后开启 loading (开启前判断 loading 是否已经开启)
请求结束后,把该请求从数组中删除(删除后判断数组内是否有别的,如果没有就关闭 loading )

这样可以保证只有一个 loading 在开启。
JKeita
2021-11-08 17:08:55 +08:00
添加拦截器?
shintendo
2021-11-08 17:12:22 +08:00
<div v-if="loading">转圈圈</div>
<div v-else>渲染数据</div>

data: {
loading: true,
数据: null
},
created () {
发请求().then(返回 => {
this.数据 = 返回
this.loading = false
})
}
elboble
2021-11-08 17:21:23 +08:00
@shintendo 这个方法可以,但是如果这样的话,每个要读数据的页面几乎都要被 v-if ,v-else 包装下,vue 是不是可以给再包装下,给我们省点事,不知道有没有装饰器。

不过实话实说,虽然数据比 mount 来的晚,但是在页面上看不出,只是控制台上会提示渲染时某个变量 undefined ,可能网络只慢了一点点,数据回来后,马上重新渲染了,人感觉不出。
learnshare
2021-11-08 17:21:25 +08:00
关注数据(状态),而非其他任何东西

你的问题核心是渲染时访问了不存在的数据,这里出了错。

有两个解法:
1. 渲染备用内容,如上面介绍的 loading 组件。发起请求前设置 loading = true ;请求结束后设置 loading = false 。根据 loading 决定渲染什么。
2. 模板里检查数据是否可用。user && user.id
learnshare
2021-11-08 17:24:46 +08:00
@elboble 不要假设请求能够瞬间完成
B 站某个 JS 加载了几十秒,页面完全死掉

v-if 有什么错,模板里有逻辑就是很繁琐
peterczg
2021-11-08 17:39:24 +08:00
楼主认为这是一个「问题」,意思是 Vue.js 框架本身有问题吗?是觉得 Vue.js 的每个 Hook 都设计成 async 模式吗?在生命周期函数里面进行异步操作,要等异步操作完成才能执行下一个钩子吗?

如果你想这么做,也不是不行,把 Vue.js 源码拷一份过来,把里面所有的 Hook 都改成 async 调用。然后书写的业务代码如下
```js
export default {
async created(){
await axios('')
},
mounted(){
},
}
```

如果你没有理清同步与异步的关系,那暂且认定你是个写 Vue.js 的新手,因为不管是在 Vue.js created 钩子和 React 已经废弃的 componentWillMount 钩子里面,都是同步调用。
elboble
2021-11-08 17:39:39 +08:00
@learnshare 自己学艺不精啊,都只教到在 created 和 mounted 里发 ajax 获数据,但是没教怎么处理异步函数返回是不确定的,v-if 加起来。
elboble
2021-11-08 17:46:53 +08:00
@learnshare 是的,昨天第一次 webpack 打包,发现加了 elmentUI ,第一个页面有 4M 多,一个 js 3M ,这 4G 网络差一点都够呛,深切体会到移动互联网在 4G 上才能爆发。

后话,删了 elmentUI 先用 bootstrap 吧
elboble
2021-11-08 17:50:38 +08:00
@peterczg 思维定式比较严重了,但是异步函数处理起来的确很头疼。写过一个 H5 页面里,几个消息要传递,还有回调,都是异步的,套了好几层。

异步函数有点像管杀不管埋,反正活干完了,后面怎么配合你自己想办法吧
M003
2021-11-08 17:54:40 +08:00
@elboble 可以尝试把 elementUI 提出去,采用 CDN 方式 不打包进去。
simple233
2021-11-08 17:57:28 +08:00
如果是用 elementUI ,建议看看 loading 组件,并且自带 v-loading 指令。。
如果不是,自己写一个自定义指令(谷歌搜一下都有),用法:<div v-loading="loading" > </div>
loading 为布尔值,true 为 loading 状态,false 显示原本页面。
douxc
2021-11-08 18:07:19 +08:00
1 、在 mounted 里发请求
2 、楼上任意一个回复都能实现
christin
2021-11-08 19:57:47 +08:00
@M003 防抖不就是用在这里的嘛 你的方法有些繁琐
darknoll
2021-11-08 20:13:23 +08:00
这是异步的问题,你直接用 v-if 判断就行了
M003
2021-11-09 09:47:52 +08:00
@christin 可以提出来,这样我也学习学习,那个方法也是在视频中学习到的。
dfkjgklfdjg
2021-11-09 09:53:07 +08:00
呃....除了吐槽你《 mounted 前没返回》异步数据这个,
之外想和你说不喜欢 loading 的,你也可以试试看骨架屏.....
christin
2021-11-09 09:58:20 +08:00
@M003 可以百度搜索 loading 闪烁 有很多使用防抖的例子 我就不嫌丑了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/813921

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX