Vue/Nuxt中beforeCreate调用Promise后created无法读取getter值如何处理
问题原因
你的判断完全正确,Vue的生命周期钩子是同步执行的:beforeCreate触发后会立刻运行created,不会等待内部异步请求(比如你封装的axios接口)完成。同时你的代码存在两处笔误也会影响取值:
- Store导出的取值对象命名错误:你写的是
export const getter = {},Vuex要求必须命名为getters才会自动注册 commit调用缺少参数分隔符:commit("setCurrent" res)需改为commit("setCurrent", res)
修复方案
第一步:先修复Store代码,返回Promise
首先修改action,将axios请求的Promise返回,方便后续等待异步执行完成:
export const state = () => ({ current: {} }); export const mutations ={ setCurrent: (state, c) => (state.current = c) } // 这里改名getters export const getters = { current: state => state.current } export const actions = { setCurrent({commit, rootState}){ // 新增return,把请求的Promise返回 return this.$axios.$get('/api/user/current', {headers: rootState.sessionUser.current}) .then(res => { console.log(res) // 加逗号分隔参数 commit("setCurrent", res) }) } }
第二步:选择适合你的组件取值方案
方案1:async/await 等待异步完成(最贴合你原本的逻辑)
通过把Promise挂到组件实例上,在created中等待请求完成再取值:
data(){ return{currentUser: null} }, beforeCreate(){ // 将请求返回的Promise挂到实例上 this.userFetchPromise = this.$store.dispatch('users/setCurrent') }, // created声明为异步函数 async created(){ // 等待请求完成再取值 await this.userFetchPromise this.currentUser = this.$store.getters['users/current'].displayname }
方案2:响应式计算属性(最推荐,符合Vue设计思路)
不用手动等待异步执行,利用Vue的响应式特性,数据更新后自动同步:
data(){ return{} }, computed: { currentUser(){ // 加可选链避免请求未完成时state为空报错 return this.$store.getters['users/current']?.displayname || null } }, beforeCreate(){ this.$store.dispatch('users/setCurrent') }
这种方式不需要处理异步回调,只要Store中current更新,currentUser会自动同步,绑定的视图也会实时刷新。
方案3:路由守卫预拉取(适合全局需要用户信息的场景)
如果当前用户信息是所有页面都需要的基础数据,可以在路由守卫中完成请求,等数据拉取完成再进入页面,组件初始化时可以直接同步取值:
// 路由配置文件中添加 router.beforeEach(async (to, from, next) => { // 已经拉取过用户信息就不用重复请求 if (!store.getters['users/current']?.id) { await store.dispatch('users/setCurrent') } next() })
这样配置后组件内可以直接在created中同步读取getter,不需要额外处理异步。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

