我希望在應用程式中的其他任何內容之前運行一些代碼,該代碼將向后端發送請求,然后更新商店。我需要先執行那部分,因為路由守衛依賴于它,如何實作?
代碼示例
獲取用戶資訊和設定
async init() {
await AuthService.initCSRF();
await AuthService.getUser().then((res) => {
if (res.data && res.data.user) {
this.loginLocally(res.data.user);
} else {
this.logoutLocally();
}
});
}
授權守衛
export function isLoggedIn(to, from, next) {
console.log('Checked', store.state.auth.isLoggedIn);
if (store.state.auth.isLoggedIn) {
next();
return;
}
next({ name: 'login' })
}
uj5u.com熱心網友回復:
在我的舊專案中,我做了這樣的事情。希望你有所了解。
應用程式.js
import App from './components/App.vue'
store.dispatch('auth/attempt', sessionStorage.getItem('token')).then(() =>{
new Vue({
el: '#app',
router,
store,
render: h => h(App),
});
});
在這里,我正在驗證在呈現應用程式之前保存在本地存盤中的令牌。
我的 Vuex 動作是這樣的
async signIn({dispatch}, credentials) {
let response = await axios.post("auth/signin", credentials);
await dispatch('attempt', response.data.token)
},
async attempt({commit, state}, token) {
if (token) {
await commit('SET_TOKEN', token);
}
if (!state.token) {
return;
}
try {
let response = await axios.get('auth/me');
commit('SET_USER', response.data)
} catch (e) {
commit('SET_TOKEN', null);
commit('SET_USER', null);
}
},
async signOut({commit}) {
axios.post('auth/signout').then(() => {
commit('SET_TOKEN', null);
commit('SET_USER', null);
});
}
我正在使用訂閱者來監聽變更并在請求標頭中添加或洗掉令牌
import store from '../store'
store.subscribe((mutation) => {
if (mutation.type === 'auth/SET_TOKEN') {
if (mutation.payload) {
axios.defaults.headers.common['Authorization'] = `Bearer ${mutation.payload}`;
sessionStorage.setItem('token', mutation.payload);
} else {
axios.defaults.headers.common['Authorization'] = null;
sessionStorage.removeItem('token');
}
}
});
最后一個用于處理令牌過期的 axios 攔截器。
import router from '../plugins/router'
import store from '../store'
import axios from "axios";
axios.interceptors.response.use((response) => {
return response;
}, (error) => {
if (error.response.status) {
if (error.response.status === 401) {
if (router.currentRoute.name !== 'landing') {
store.dispatch('auth/clearToken').then(() => {
router.replace({
name: 'landing'
});
}).finally(() => {
swal.fire(
'Your Session is Expired',
'Please sign in again!',
'error'
)
});
}
}
}
return Promise.reject(error);
});
uj5u.com熱心網友回復:
初始化承諾可以在呼叫之前等待.mount(...)。問題是Vue路由器與應用程式分開啟動,不會以這種方式延遲。
如果是路由器依賴初始化程序,延遲路由器啟動的一種方法是等待路由器鉤子中的promise在其他鉤子之前觸發:
const initPromise = init();
...
router.beforeEach(async (to, from, next) => {
await initPromise;
next();
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/400266.html
