關于EventBus
EventBus是一個事件發布/訂閱模式的實現,它允許不同的組件或模塊之間進行通信,而不需要直接引用對方。這種模式特別適用于那些需要跨組件傳遞信息,但又不想引入復雜依賴關系的場景。
實現思路
- 利用axios中間件,在axios中攔截401的code狀態碼,攔截到之后,發起events事件
- 在app.tsx中監聽,然后跳轉頁面
為什么不使用window.localtion = xxxx跳轉?這樣破壞單頁面應用的交互,使用window.location 頁面會直接刷新。
為什么不直接使用navigate跳轉? navigate只能在組件中使用。
實現步驟
實現EventBus
新建一個event.js文件
import { EventEmitter } from 'events';
const eventBus = new EventEmitter()export default eventBus;
在axios中進行攔截時使用
import axios from 'axios';
import EventBus from './event'
const instance = axios.create({
})
instance.interceptors.response.use(function (response) {if (response.status === 200) {if (response.data.code === 401) {// 此時用戶沒有進行登錄EventBus.emit('global_not_login', response.data.msg)}if (response.data.code === -1) {EventBus.emit('global_error_tips', response.data.msg)}} else if (response.status === 403) {EventBus.emit('global_error_auth', '沒有權限,別瞎訪問')}return response;
}, function (error) {EventBus.emit('global_error_tips', error.response.data.message)return Promise.reject(error);
});
export type AxiosRes<T = ResData> = {config: Object,data: T,headers: any,request: any,status: number,statusText: string
}
export type ResData<T = any> = {code: number,msg: string,data: T
}
export type AxiosResData<T = any> = AxiosRes<ResData<T>>
export default instance
在app.ts頁面進行監聽
部分代碼如下,核心就是在useEffect使用EventBus.on訂閱global_not_login這個事件,檢測到事件的發出,則跳轉到登錄頁面
function App() {const navigate = useNavigate()useEffect(()=>{EventBus.on('global_not_login', function (msg) {navigate('/login')})}, [])return (<Routes><Route path="/" element={<Navigate to={'/login'}></Navigate>}></Route>{/* 頁面1 登錄 */}<Route path={routersData.login.path} element={<Login />}></Route></Routes>)
}