如何从外部JavaScript函数访问Vue组件data与router实例
Vue通用请求状态码处理中间件解决方案
核心问题修复方案
问题1:中间件内访问router实例
Vue Router创建的是全局单例实例,直接在中间件文件头部导入你项目中定义的router实例即可:
- 如果你项目用CommonJS规范:
const router = require('@/router/index').default - 如果你项目用ES模块规范:
import router from '@/router/index'
导入后直接在中间件内调用router.push即可,不需要额外处理。
问题2:修改调用组件的error属性
你当前中间件的this没有绑定到调用请求的组件实例,只需要在调用时将组件实例作为参数传入中间件即可:
- 调整中间件参数,新增接收组件实例的入参
- 400状态码逻辑中用传入的组件实例修改error属性
完整修改后的代码示例
中间件代码
// 导入项目全局router单例,路径替换为你实际router文件的路径 import router from '@/router' import axios from 'axios' export const serverErrorMiddleware = async (res, componentInstance) => { const status = res.status if (status === 500) return router.push('/error') if (status === 404) return router.push('/notfound') if (status === 302) return router.push('/login') if (status === 403 && !res.error.isrefTokenError) return router.push('/unauthorized') // 用传入的组件实例修改error值 if (status === 400 && componentInstance) componentInstance.error = res.error.message if (status === 401) { if (!localStorage.getItem('refresh_token')) return router.push('/login') try { const response = await axios({ method: 'get', url: 'http://localhost:5000/api/auth/newtoken' }) localStorage.setItem('access_token', response.auth.accessToken) // 可新增逻辑:刷新token成功后重试原请求,优化用户体验 } catch (err) { if (err.response.status === 403 && err.response.error.isrefTokenError) return router.push('/login') router.push('/error') } } }
组件内调用代码
async submitForm(event) { event.preventDefault() try { const response = await axios({ method: 'post', url: 'http://localhost:5000/api/auth/register', data: { username: this.formData.username, password: this.formData.password } }) console.log(response) } catch (err) { // 把当前组件实例this作为第二个参数传入 await serverErrorMiddleware(err.response, this) } }
可选优化方案
你可以将该逻辑直接封装为axios全局响应拦截器,不需要在每个请求的catch块中手动调用,复用效率更高:
// 全局axios拦截器配置,放在main.js或者单独的axios配置文件中 axios.interceptors.response.use( (response) => response, async (error) => { if (error.response) { // 直接调用中间件,需要修改组件error的场景再额外处理 await serverErrorMiddleware(error.response, error.config.componentInstance) } return Promise.reject(error) } )
内容的提问来源于stack exchange,提问作者Ganesh Dagadi
相关产品推荐
相关产品推荐

