淺析Vue3中useRouter怎么在Vue組件外使用
useRouter 是 Vue 3 Composition API 中的鉤子(hook),它只能在 Vue 組件中使用,而不是在普通的 JavaScript 模塊或工具函數(shù)中。
為了在攔截器中使用 router,你需要在 Axios 響應(yīng)攔截器中獲取到 router 實(shí)例。你可以通過以下兩種方式來解決這個(gè)問題:
方案 1:將 router 作為參數(shù)傳遞到攔截器中
一種常見的解決方案是在設(shè)置 Axios 實(shí)例時(shí),把 router 作為參數(shù)傳遞給需要使用它的地方。你可以通過 Vue 的全局狀態(tài)(比如 Vuex 或 Pinia)來存儲(chǔ) router 實(shí)例,然后在攔截器中使用它。
步驟:
1.在主應(yīng)用中傳遞 router:
你可以在你的 Vue 應(yīng)用的主組件(比如 App.vue)中獲取 router 實(shí)例并將其存儲(chǔ)在 Vuex 或 Pinia 中。
2.在 Axios 中使用 router:
你可以在響應(yīng)攔截器中訪問存儲(chǔ)的 router 實(shí)例,進(jìn)而進(jìn)行路由跳轉(zhuǎn)。
示例實(shí)現(xiàn):
在 store.js 或 Pinia 中存儲(chǔ) router 實(shí)例:
store.js (假設(shè)你使用 Pinia 或 Vuex 來管理全局狀態(tài))
在Pinia定義一個(gè)變量用來存儲(chǔ)router
// 用來存儲(chǔ) router 實(shí)例 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 配置文件,使用存儲(chǔ)的 router 實(shí)例:
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()
// 添加請(qǐng)求攔截器
// https://axios-http.com/zh/docs/interceptors
sender.interceptors.request.use(function (config) {
// console.log('請(qǐng)求攔截器')
// 統(tǒng)一添加 token 請(qǐng)求頭
config.headers['Authorization'] = appStore.token
return config;
}, function (error) {
// console.log('請(qǐng)求攔截器 error: ', error)
// 對(duì)請(qǐng)求錯(cuò)誤做些什么
return Promise.reject(error);
});
// 添加響應(yīng)攔截器
sender.interceptors.response.use(function (response) {
// console.log('響應(yīng)攔截器', response)
// 2xx 范圍內(nèi)的狀態(tài)碼都會(huì)觸發(fā)該函數(shù)。
// 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么
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)碼都會(huì)觸發(fā)該函數(shù)。
// 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么
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)管理,也可以通過全局對(duì)象(如 window)來暫時(shí)存儲(chǔ) router 實(shí)例。這樣做雖然不太推薦,但也能實(shí)現(xiàn)需求。
示例實(shí)現(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 實(shí)例到 window 對(duì)象
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',
},
});
// 添加請(qǐng)求攔截器
sender.interceptors.request.use(function (config) {
// ...請(qǐng)求攔截邏輯
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)來存儲(chǔ) router 實(shí)例,這樣可以確保 router 的實(shí)例在任何需要使用它的地方都能正確獲取,而不必依賴 window 或全局對(duì)象。此外,避免將 router 直接暴露到全局中可以保持代碼的模塊化和清晰。
到此這篇關(guān)于淺析Vue3中useRouter怎么在Vue組件外使用的文章就介紹到這了,更多相關(guān)Vue3 useRouter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue.js的簡(jiǎn)單自動(dòng)求和計(jì)算實(shí)例
今天小編就為大家分享一篇vue.js的簡(jiǎn)單自動(dòng)求和計(jì)算實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Vue頁(yè)面布局與路由映射實(shí)戰(zhàn)教程之RouterView嵌套及動(dòng)態(tài)組件生成詳解
文章介紹了布局組件在Vue應(yīng)用中的設(shè)計(jì)和使用,包括布局組件的核心作用、多層RouterView的嵌套布局、靜態(tài)組件與動(dòng)態(tài)組件的區(qū)別,以及動(dòng)態(tài)路由的優(yōu)勢(shì),通過這些機(jī)制,可以實(shí)現(xiàn)界面的一致性、靈活的權(quán)限控制和菜單擴(kuò)展,感興趣的朋友跟隨小編一起看看吧2026-01-01
使用vue-router完成簡(jiǎn)單導(dǎo)航功能【推薦】
vue-router是Vue.js官方提供的一套專用的路由工具庫(kù)。這篇文章主要介紹了使用vue-router完成簡(jiǎn)單導(dǎo)航功能,需要的朋友可以參考下2018-06-06
Vue.use與Vue.prototype的區(qū)別及說明
這篇文章主要介紹了Vue.use與Vue.prototype的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
詳解vue 計(jì)算屬性與方法跟偵聽器區(qū)別(面試考點(diǎn))
這篇文章主要介紹了詳解vue 計(jì)算屬性與方法跟偵聽器區(qū)別(面試考點(diǎn)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
Vue3中關(guān)于getCurrentInstance的大坑及解決
這篇文章主要介紹了Vue3中關(guān)于getCurrentInstance的大坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04

