Nuxt中如何让页面等待Vuex异步action加载完所有数据后再渲染?
问题根源
你的配置不生效有两个核心原因:
- 编写的Vuex
get_postsaction没有返回Promise,async/await依赖Promise实现等待逻辑,没有返回的话Nuxt无法识别异步请求的完成状态 - 页面的fetch方法中调用dispatch时没有添加
await关键字,不会等待请求执行完成就会继续渲染页面
第一步:改造Vuex action返回Promise
给你原来的action添加返回值即可,修改后代码如下:
actions: { get_posts(ctx) { // 这里添加return把整个异步请求链返回 return axios.get("http://vengdef.com/wp-json/wp/v2/posts").then(post => { let posts = post.data; if (!posts.length) return; let medias_list = ""; posts.forEach(md => { medias_list += md.featured_media + "," }); medias_list = medias_list.slice(0, -1); let author_list = ""; posts.forEach(md => { author_list += md.author + "," }); author_list = author_list.slice(0, -1); // 这里添加return更符合异步规范 return axios.all([ axios.get("http://vengdef.com/wp-json/wp/v2/media?include=" + medias_list), axios.get("http://vengdef.com/wp-json/wp/v2/users?include=" + author_list), axios.get("http://vengdef.com/wp-json/wp/v2/categories"), ]).then(axios.spread((medias, authors, categories) => { ctx.commit("set_postlist", {medias, authors, categories} ); })).catch((err) => { console.log(err) }); }) } },
第二步:修改页面fetch方法添加await
修改后的fetch代码如下:
async fetch () { await this.$store.dispatch("posts/get_posts"); }
可选优化:添加加载状态提示
Nuxt的fetch方法自带$fetchState内置状态,你可以在模板中添加状态提示提升体验:
<template> <div> <div v-if="$fetchState.pending">数据加载中,请稍候</div> <div v-else-if="$fetchState.error">数据加载失败,请刷新页面重试</div> <div v-else> <!-- 此处渲染你的post列表数据 --> </div> </div> </template>
如果你想使用asyncData实现
asyncData无法访问this,需要从上下文参数中获取store实例,写法如下:
async asyncData({ store }) { await store.dispatch("posts/get_posts") // 可直接返回state中的数据给组件作为props使用 return { postlist: store.state.posts.postlist } }
内容的提问来源于stack exchange,提问作者user16751547
相关产品推荐
相关产品推荐

