Vuex 4 + Vue组合式API中用户对象未及时加载引发请求问题
问题:用户对象未加载完成导致后续代码执行异常
在Vue组合式API结合Vuex 4开发时,用户对象无法及时加载完成,导致组件后续依赖该对象的代码无法正常运行。
Vuex User模块代码
import axios from "axios"; const state = () => ({ user: null, userStatus: null }) const getters = { authUser: state => { return state.user } } const actions = { async fetchAuthUser({commit}) { await axios.get('/auth-user') .then(res => { commit('setAuthUser', res.data); }) .catch(error => { console.log('Unable to fetch auth user'); }); } } const mutations = { setAuthUser(state, user) { state.user = user } } export default { namespaced: true, state, getters, actions, mutations, }
组件中的问题代码
在组件中调用fetchAuthUser后,直接使用计算属性获取的用户对象调用Posts/fetchUserPosts,此时用户对象尚未加载完成,仍为null:
const store = useStore(); store.dispatch('User/fetchAuthUser'); const user = computed(() => { return store.getters['User/authUser']; }); // 此时user仍为null,访问user.data.user_id会报错 store.dispatch("Posts/fetchUserPosts", user.data.user_id);
解决方案
1. 等待用户加载完成后再执行后续操作
将异步操作放在生命周期钩子中,使用async/await确保fetchAuthUser执行完成后再调用获取帖子的action:
<script setup lang="ts"> // ... 其他导入 import {computed, onMounted} from "vue"; import {useStore} from "vuex"; const store = useStore(); const user = computed(() => store.getters['User/authUser']); onMounted(async () => { // 等待用户信息加载完成 await store.dispatch('User/fetchAuthUser'); // 此时user已存在,可安全访问user_id if (user.value) { await store.dispatch("Posts/fetchUserPosts", user.value.data.user_id); } }); // ... 其他计算属性和方法 </script>
2. 监听用户对象的变化触发后续逻辑
使用watch监听用户对象,当用户对象从null变为有效值时,执行获取帖子的操作:
<script setup lang="ts"> // ... 其他导入 import {computed, watch} from "vue"; import {useStore} from "vuex"; const store = useStore(); const user = computed(() => store.getters['User/authUser']); // 先触发用户加载 store.dispatch('User/fetchAuthUser'); // 监听user变化,当user存在时执行帖子加载 watch(user, (newUser) => { if (newUser) { store.dispatch("Posts/fetchUserPosts", newUser.data.user_id); } }, { immediate: false }); // immediate设为false,避免初始null时触发 // ... 其他计算属性和方法 </script>
3. 在Vuex中串联依赖操作(可选)
如果获取帖子的操作始终依赖用户信息,可以在fetchAuthUser成功后直接调用Posts/fetchUserPosts,减少组件层的逻辑耦合:
// 修改User模块的fetchAuthUser action async fetchAuthUser({commit, dispatch}) { try { const res = await axios.get('/auth-user'); commit('setAuthUser', res.data); // 用户加载完成后直接调用获取帖子的action await dispatch('Posts/fetchUserPosts', res.data.data.user_id); } catch (error) { console.log('Unable to fetch auth user'); } }
此时组件中只需调用fetchAuthUser即可:
store.dispatch('User/fetchAuthUser');
额外注意事项
- 访问
user.data前务必先判断user是否存在,避免出现Cannot read properties of null的错误; - 可以在模板中通过
v-if="user"控制依赖用户对象的DOM渲染,确保只有用户加载完成后才显示相关内容。
内容的提问来源于stack exchange,提问作者Danny Younes
相关产品推荐
相关产品推荐

