当前位置: 首页 > news >正文

​​Vue 拦截器教程​

​​​概念与适用场景​

在 Vue 项目中,“拦截器”通常指基于 ​​Axios​​ 的 ​​HTTP 拦截器​​,用于在请求发送前与响应返回后统一处理逻辑,例如:添加通用请求头(如 ​​Authorization​​)、统一错误处理、格式化响应数据、记录日志等。与之配合的还有 ​​Vue Router 的路由守卫​​,用于在页面跳转时进行权限校验与重定向。两者结合,可实现鉴权、登录跳转、全局加载与错误提示等常见能力。

​HTTP 拦截器快速上手​

  • 安装与创建实例
    使用 ​​axios.create​​ 创建独立实例,避免污染全局配置,并便于按环境切换 ​​baseURL​​、​​timeout​​ 等。
  • 添加请求拦截器
    在请求发出前统一处理,如注入 ​​token​​、设置超时、开启全屏 ​​Loading​​ 等。
  • 添加响应拦截器
    统一处理业务状态码与 ​​HTTP 状态码​​,如遇到 ​​401​​ 清除本地凭证并跳转登录页。
  • 在组件中使用
    直接使用封装好的实例发起请求,拦截器会自动生效。

示例代码(src/utils/request.js):

// src/utils/request.js
import axios from 'axios'
import router from '@/router'
import { Message } from 'element-ui' // 可替换为你项目的提示组件const http = axios.create({baseURL: import.meta.env.VITE_API_BASE_URL || '/api',timeout: 10000
})// 请求拦截器
http.interceptors.request.use((config) => {const token = localStorage.getItem('token')if (token) {config.headers.Authorization = `Bearer ${token}`}// 可在此开启全屏 loading// store.dispatch('app/showLoading', true)return config},(error) => Promise.reject(error)
)// 响应拦截器
http.interceptors.response.use((response) => {// 可在此关闭全屏 loading// store.dispatch('app/showLoading', false)// 若后端约定 data 为业务数据,可直接返回 response.datareturn response},(error) => {// 关闭全屏 loading// store.dispatch('app/showLoading', false)if (error.response) {const { status, data } = error.responseif (status === 401) {localStorage.removeItem('token')router.replace({path: '/login',query: { redirect: router.currentRoute.fullPath }})} else {// 业务或 HTTP 错误提示Message.error(data?.message || `请求失败(${status})`)}} else if (error.request) {Message.error('网络错误,请检查网络连接')} else {Message.error('请求配置错误:' + error.message)}return Promise.reject(error)}
)export default http

在入口文件挂载(可选,便于在插件/工具中直接使用):

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import http from './utils/request'const app = createApp(App)
app.config.globalProperties.$http = http
app.use(router).mount('#app')

在组件中使用:

// 选项式 API
import http from '@/utils/request'
export default {async created() {try {const res = await http.get('/users')console.log(res.data)} catch (err) {// 错误已在拦截器中统一提示,此处可按需处理}}
}// 组合式 API
import { getCurrentInstance } from 'vue'
import http from '@/utils/request'
export default {setup() {const { proxy } = getCurrentInstance()const fetchData = async () => {const res = await http.get('/users')console.log(res.data)}return { fetchData }}
}

​路由拦截与鉴权​

  • 在路由定义中使用 ​​meta 字段​​ 标识需要登录的页面(如 requireAuth: true)。
  • 使用 ​​router.beforeEach​​ 全局前置守卫进行拦截:若目标路由需要登录且本地无 ​​token​​,则重定向到登录页,并携带 ​​redirect​​ 以便登录后回跳。
  • 结合 HTTP 拦截器处理 ​​401​​:当后端返回未授权时,清除本地凭证并跳转登录,保证前端与后端状态一致。

示例代码(src/router/index.js):

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Login from '@/views/Login.vue'
import Home from '@/views/Home.vue'const router = createRouter({history: createWebHistory(),routes: [{ path: '/login', name: 'Login', component: Login, meta: { auth: false } },{ path: '/', name: 'Home', component: Home, meta: { requireAuth: true } }]
})router.beforeEach((to, from, next) => {const token = localStorage.getItem('token')const requiresAuth = to.meta.requireAuthif (requiresAuth && !token) {next({path: '/login',query: { redirect: to.fullPath }})} else {next()}
})export default router

​最佳实践与常见问题​

  • 使用独立实例
    通过 ​​axios.create​​ 创建实例并导出,避免直接修改全局 axios,便于多环境与多业务线维护。
  • 不要在拦截器中放入副作用逻辑
    如非必要,避免在拦截器内直接修改全局状态或触发复杂副作用,保持拦截器职责单一与可预测性。
  • 区分 HTTP 状态码与业务状态码
    ​401/403/500​​ 等为 HTTP 状态码,通常在响应拦截器处理;业务成功与否常由后端在响应体中的 ​​code/message​​ 字段表达,需按业务约定判断并在拦截器或业务层处理。
  • 统一错误提示与加载状态
    可在响应拦截器中集成全局提示(如 ​​Message​​)与 ​​Loading​​,避免每个请求重复编写,注意避免重复关闭或在错误分支遗漏关闭。
  • 登录跳转携带目标路径
    使用 query: { redirect: to.fullPath } 保存来源地址,登录成功后跳转回原页面,提升体验。
  • 配置与环境分离
    将 ​​baseURL、timeout、withCredentials​​ 等抽离到环境变量或配置文件,便于开发、测试、生产多环境切换。
http://www.dtcms.com/a/613602.html

相关文章:

  • 科普:.NET应用开发的环境搭建
  • cn域名后缀网站南通网站建设南通
  • Kafka集群架构(ZK + Kafka)
  • 编程语言哪种编译器好 | 如何选择适合自己的编译器,提高开发效率
  • 【原创】基于YOLO模型的手势识别系统
  • 11.15 脚本网页 剪切板管家
  • 基于python代码自动生成关于建筑安全检测的报告
  • 【Chrono库】Chrono Traits 模块解析(traits.rs)
  • Go语言使用的编译器 | 探索Go编程语言的工具链和编译过程
  • Logback,SLF4J的经典后继日志实现!
  • 搭建个人知识库
  • leetcode寻找第k大的值
  • 瑞安外贸网站制作php做网站都需要学什么软件
  • 企业级 Spring Boot + WebSocket + Redis 分布式消息推送方案
  • 线性代数 · SVD | 从线性代数到数据科学的“盛大”应用(scr:bzv)
  • 专门做推广的网站吗做当地门户网站多少钱
  • 【Java Web学习 | 第12篇】JavaScript(6)DOM
  • VVIC item_search 接口对接全攻略:从入门到精通
  • 四川住建厅官方网站的网址北京专业建设
  • 网站开发实训课程的总结手机网游
  • 《道德经》第五十八章
  • 【面试经验】梅赛德斯奔驰X-Seed AI Systems - Autonomous Driving Agent Efficiency
  • MATLAB基于CNN和DE-NSGAIII的齿盘切削参数优化
  • Node.js+Vue的学习笔记
  • 哪些网站设计的好嘉兴互联网公司
  • GM-3568JHF丨ARM+FPGA异构开发板系列教程:基础入门 1- 开发环境搭建
  • 从括号匹配到字符串解码:递归思想的巧妙应用
  • 第7章 Node框架实战篇 - Express 中间件与RESTful API 接口规范
  • 编译器用什么语言开发 | 深入探讨编译器开发的语言选择及其影响
  • 实战内网PTH上线域控