欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > Vue3中useRouter 怎么在Vue 组件外使用

Vue3中useRouter 怎么在Vue 组件外使用

2024/11/14 15:03:20 来源:https://blog.csdn.net/qq_48763502/article/details/143586536  浏览:    关键词:Vue3中useRouter 怎么在Vue 组件外使用

useRouter 是 Vue 3 Composition API 中的钩子(hook),它只能在 Vue 组件中使用,而不是在普通的 JavaScript 模块或工具函数中。

为了在拦截器中使用 router,你需要在 Axios 响应拦截器中获取到 router 实例。你可以通过以下两种方式来解决这个问题:

方案 1:将 router 作为参数传递到拦截器中

一种常见的解决方案是在设置 Axios 实例时,把 router 作为参数传递给需要使用它的地方。你可以通过 Vue 的全局状态(比如 Vuex 或 Pinia)来存储 router 实例,然后在拦截器中使用它。

步骤:

  1. 在主应用中传递 router:

你可以在你的 Vue 应用的主组件(比如 App.vue)中获取 router 实例并将其存储在 Vuex 或 Pinia 中。

  1. 在 Axios 中使用 router:

你可以在响应拦截器中访问存储的 router 实例,进而进行路由跳转。

示例实现:

  1. 在 store.js 或 Pinia 中存储 router 实例:

// store.js (假设你使用 Pinia 或 Vuex 来管理全局状态)
在Pinia定义一个变量用来存储router

// 用来存储 router 实例let router  =ref(null)
  1. 在 App.vue 中将 router 存入 store:
    在app.vue中给Pinia定义的变量赋值
import { useRouter } from 'vue-router'
const router = useRouter()const appStore = getAppStore()
appStore.router = router
  1. 修改 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('请求拦截器')// 统一添加 token 请求头config.headers['Authorization'] = appStore.tokenreturn config;
}, function (error) {// console.log('请求拦截器 error: ', error)// 对请求错误做些什么return Promise.reject(error);
});// 添加响应拦截器
sender.interceptors.response.use(function (response) {// console.log('响应拦截器', response)// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么appStore.loading = falseif (response.headers.token) {appStore.token = response.headers.token// console.log('update token '+response.headers.token)}return response.data
}, function (error) {// console.log('响应拦截器 error: ', error)// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么appStore.loading = falseif (error.status === 401) {appStore.isLogin = falseappStore.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

如果你不想使用全局状态管理,也可以通过全局对象(如 window)来暂时存储 router 实例。这样做虽然不太推荐,但也能实现需求。

示例实现:

  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');
  1. 在 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);
});// 添加响应拦截器
sender.interceptors.response.use(function (response) {// ...响应拦截逻辑return response.data;
}, function (error) {// 使用 window.appRouter 进行路由跳转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;

总结
最好的方法是通过全局状态管理(如 Pinia 或 Vuex)来存储 router 实例,这样可以确保 router 的实例在任何需要使用它的地方都能正确获取,而不必依赖 window 或全局对象。此外,避免将 router 直接暴露到全局中可以保持代码的模块化和清晰。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com