Vue中router.beforeEach守卫里Async/Await未按预期工作求助
Hey there! Let's break down why your await isn't behaving as expected in the router guard, and fix it step by step.
Core Issue: Your Vuex Action Doesn't Return a Promise
The main problem is that your GetPermission action isn't returning the Promise from your axios request. When you use await on a function that doesn't return a Promise, it doesn't wait for the async operation to finish—so your code proceeds to check store.state.permissions before the API call completes and the mutation updates the state.
Fix the Vuex Action
Update your GetPermission action to return the axios Promise (or use async/await inside the action, which automatically returns a Promise):
Option 1: Return the axios request directly
GetPermission(context) { axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token; // Return the Promise so await can wait for it return axios.get('http://127.0.0.1:8000/api/user') .then((response) => { console.log(response); context.commit('Permissions', response.data.permission); }); }
Option 2: Use async/await in the action
async GetPermission(context) { axios.defaults.headers.common['Authorization'] = 'Bearer ' + context.state.token; const response = await axios.get('http://127.0.0.1:8000/api/user'); console.log(response); context.commit('Permissions', response.data.permission); }
Additional Fixes to Avoid Other Issues
Set a proper initial value for
permissions
In your Vuex state, you havepermissions: ''(an empty string), but you're trying to usefilter()(an array method) on it later. This will throw an error initially. Change the initial value to an empty array:state: { error: '', token: localStorage.getItem('token') || null, permissions: [], // Empty array instead of empty string success: '', isLoggedin: '', LoggedUser: {} }Fix the permission check logic
Your current filter check has a syntax error—you're wrapping the condition in parentheses incorrectly, which will lead to wrong results. Update it to usesome()(more efficient thanfilter().length !== 0since it stops searching at the first match):if (permissions.some(per => per.name === 'read_list')) { next({ path: '/dashboard/create' }); } else { next(); }
Final Router Guard Code
After applying the fixes, your router guard should work as expected:
router.beforeEach(async (to, from, next) => { await store.dispatch('GetPermission'); if (to.matched.some(record => record.meta.requireAuth)) { const permissions = store.state.permissions; console.log(permissions); // Now this will have the data from the API if (permissions.some(per => per.name === 'read_list')) { next({ path: '/dashboard/create' }); } else { next(); } } else { next(); } });
内容的提问来源于stack exchange,提问作者Gunaraj Khatri

