const router = createRouter({
history,
routes,
})
router.beforeEach(async (to, from) => {
if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in')) {
return true
} else {
const path = await http.get('/me').then(() => true, () => '/sign_in?return_to=' + to.path)
return true
}
})
问题1: 上面的代码每次路由跳转的时候都会调用 me 接口
解决方法:如果我们不想每次路由跳转都调用接口我们可以把接口调用写在外面
const promise = http.get('/me')
router.beforeEach(async (to, from) => {
if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in') || to.path.startsWith('/start')) {
return true
} else {
const path = await promise.then(() => true, () => '/sign_in?return_to=' + to.path)
return path
}
})
问题2:上面接口是只调一次了,但是我们登录成功后页面不会跳转
原因:以登录成功后跳转 http://localhost:8082/#/sign_in?return_to=/items/create 为例,我们的 /me 接口依赖 jwt,没登录就没有 jwt,所以一开始我们未登录从 items/create 跳到 sign_in 没问题,但是登录成功后因为我们的 /me 接口只在初始化的时候调用,所以即使我们登录成功这个接口还是走的一开始的 catch 所以还是跳到了登录页
解决方法:在用户登录成功成功后主动去更新
me.tsx
import {
AxiosResponse } from "axios";
import {
http } from "./Http";
export let mePromise: Promise<AxiosResponse<{
resource: {
id: number
}
}>> | undefined
export const refreshMe = () => {
mePromise = http.get<{
resource: {
id: number }}>('/me')
return mePromise
}
export const fetchMe = refreshMe
signInPage
// 点击登录按钮后
refreshMe()
router.push(returnTo || '/')
main.ts
import {
mePromise, fetchMe } from './shared/me';
fetchMe()
router.beforeEach(async (to, from) => {
if (to.path === '/' || to.path.startsWith('/welcome') || to.path.startsWith('/sign_in') || to.path.startsWith('/start')) {
return true
} else {
const path = await mePromise!.then(() => true, () => '/sign_in?return_to=' + to.path)
return path
}
})