淺析Vue3中useRouter怎么在Vue組件外使用
useRouter 是 Vue 3 Composition API 中的鉤子(hook),它只能在 Vue 組件中使用,而不是在普通的 JavaScript 模塊或工具函數(shù)中。
為了在攔截器中使用 router,你需要在 Axios 響應(yīng)攔截器中獲取到 router 實例。你可以通過以下兩種方式來解決這個問題:
方案 1:將 router 作為參數(shù)傳遞到攔截器中
一種常見的解決方案是在設(shè)置 Axios 實例時,把 router 作為參數(shù)傳遞給需要使用它的地方。你可以通過 Vue 的全局狀態(tài)(比如 Vuex 或 Pinia)來存儲 router 實例,然后在攔截器中使用它。
步驟:
1.在主應(yīng)用中傳遞 router:
你可以在你的 Vue 應(yīng)用的主組件(比如 App.vue)中獲取 router 實例并將其存儲在 Vuex 或 Pinia 中。
2.在 Axios 中使用 router:
你可以在響應(yīng)攔截器中訪問存儲的 router 實例,進(jìn)而進(jìn)行路由跳轉(zhuǎn)。
示例實現(xiàn):
在 store.js 或 Pinia 中存儲 router 實例:
store.js (假設(shè)你使用 Pinia 或 Vuex 來管理全局狀態(tài))
在Pinia定義一個變量用來存儲router
// 用來存儲 router 實例 let router =ref(null)
在 App.vue 中將 router 存入 store:
在app.vue中給Pinia定義的變量賦值
import { useRouter } from 'vue-router' const router = useRouter() const appStore = getAppStore() appStore.router = router
修改 Axios 配置文件,使用存儲的 router 實例:
import axios from 'axios' import { getAppStore } from '../store' import { showDialog } from 'vant' import { useRouter } from 'vue-router'; const router = useRouter() const sender = axios.create({ baseURL: import.meta.env.PROD ? import.meta.env.VITE_API_TARGET : 'api', headers: { 'Content-Type': 'application/json' } }); const appStore = getAppStore() // const router = useRouter() // 添加請求攔截器 // https://axios-http.com/zh/docs/interceptors sender.interceptors.request.use(function (config) { // console.log('請求攔截器') // 統(tǒng)一添加 token 請求頭 config.headers['Authorization'] = appStore.token return config; }, function (error) { // console.log('請求攔截器 error: ', error) // 對請求錯誤做些什么 return Promise.reject(error); }); // 添加響應(yīng)攔截器 sender.interceptors.response.use(function (response) { // console.log('響應(yīng)攔截器', response) // 2xx 范圍內(nèi)的狀態(tài)碼都會觸發(fā)該函數(shù)。 // 對響應(yīng)數(shù)據(jù)做點什么 appStore.loading = false if (response.headers.token) { appStore.token = response.headers.token // console.log('update token '+response.headers.token) } return response.data }, function (error) { // console.log('響應(yīng)攔截器 error: ', error) // 超出 2xx 范圍的狀態(tài)碼都會觸發(fā)該函數(shù)。 // 對響應(yīng)錯誤做點什么 appStore.loading = false if (error.status === 401) { appStore.isLogin = false appStore.token = '' const router = appStore.router; router.push('/login') } if (error.status === 422) { showDialog({ teleport: '#main', className: 'global-dialog', showConfirmButton: false, closeOnClickOverlay: true, message: error.response.data.message }) } return Promise.reject(error) }); export const send = sender
方案 2:通過 window 或 global 暴露 router
如果你不想使用全局狀態(tài)管理,也可以通過全局對象(如 window)來暫時存儲 router 實例。這樣做雖然不太推薦,但也能實現(xiàn)需求。
示例實現(xiàn):
1.在 App.vue 中將 router 暴露到 window 上:
// App.vue import { createApp } from 'vue'; import App from './App.vue'; import { createRouter } from 'vue-router'; import { routes } from './router'; const router = createRouter({ history: createWebHistory(), routes, }); // 暴露 router 實例到 window 對象 window.appRouter = router; const app = createApp(App); app.use(router).mount('#app');
2.在 Axios 配置中直接使用 window.appRouter:
// axios.js import axios from 'axios'; import { showDialog } from 'vant'; const sender = axios.create({ baseURL: import.meta.env.PROD ? import.meta.env.VITE_API_TARGET : 'api', headers: { 'Content-Type': 'application/json', }, }); // 添加請求攔截器 sender.interceptors.request.use(function (config) { // ...請求攔截邏輯 return config; }, function (error) { return Promise.reject(error); }); // 添加響應(yīng)攔截器 sender.interceptors.response.use(function (response) { // ...響應(yīng)攔截邏輯 return response.data; }, function (error) { // 使用 window.appRouter 進(jìn)行路由跳轉(zhuǎn) if (error.status === 422) { const router = window.appRouter; if (router) { router.push('/login'); showDialog({ teleport: '#main', className: 'global-dialog', showConfirmButton: false, closeOnClickOverlay: true, message: error.response.data.message, }); } } return Promise.reject(error); }); export const send = sender;
總結(jié)
最好的方法是通過全局狀態(tài)管理(如 Pinia 或 Vuex)來存儲 router 實例,這樣可以確保 router 的實例在任何需要使用它的地方都能正確獲取,而不必依賴 window 或全局對象。此外,避免將 router 直接暴露到全局中可以保持代碼的模塊化和清晰。
到此這篇關(guān)于淺析Vue3中useRouter怎么在Vue組件外使用的文章就介紹到這了,更多相關(guān)Vue3 useRouter內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實現(xiàn)移動端可拖拽式icon圖標(biāo)
這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)移動端可拖拽式icon圖標(biāo),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03Vue文件如何代替?zhèn)鹘y(tǒng)的HTML文件
隨著前端工程化的不斷推進(jìn),傳統(tǒng)的HTML、CSS、JavaScript三者分離的開發(fā)模式逐漸顯露出一些不足之處,尤其是在構(gòu)建復(fù)雜的單頁應(yīng)用(SPA)時,Vue.js作為一個現(xiàn)代化的前端框架,提供了多種工具和技術(shù)來簡化開發(fā)流程,本文將探討.vue文件是如何替代傳統(tǒng)HTML文件的角色2024-10-10利用Vue實現(xiàn)一個markdown編輯器實例代碼
這篇文章主要給大家介紹了關(guān)于如何利用Vue實現(xiàn)一個markdown編輯器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05vue使用Highcharts實現(xiàn)不同高度的3D環(huán)形圖
這篇文章主要為大家詳細(xì)介紹了vue使用Highcharts實現(xiàn)不同高度的3D環(huán)形圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03Vue 實現(xiàn)把表單form數(shù)據(jù) 轉(zhuǎn)化成json格式的數(shù)據(jù)
今天小編就為大家分享一篇Vue 實現(xiàn)把表單form數(shù)據(jù) 轉(zhuǎn)化成json格式的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10