网站首页 > 技术文章 正文
配置request.ts
/**
* axios 二次封装
* @auther 何小生。
* @time 2021/08/05 05:24
*/
import axios from 'axios' // 引入axios
import { config } from '../config' // 引入config
import { ElMessage } from 'element-plus' // 引入element-plus
import router from '../router' // 由于有些token认证失效等需要用到,所以引入router
import { storage } from './storage' // 引入storage,用于获取缓存
// 定义初始化状态码
const TOKEN_INVALID = 'Token认证失败, 请重新登录'
const NETWORK_ERROR = '网络请求异常, 请稍后重试'
// 创建axios实例对象, 添加全局配置
const service = axios.create({
// 初始配置请求头 当环境为mock的时候,请求mockapi,否则请求正式的api
baseURL: config.mock ? config.mockApi : config.baseApi,
// 接口持续时间为8秒,否则超时
timeout: 8000
})
// 请求拦截
service.interceptors.request.use((req) => {
// TO-DO
// 获取请求头
const headers = req.headers
// 获取token 由于是typescript,所以要做排斥赋值
const { token = "" } = storage.get('userInfo') || {}
// 跟后端定义的某个请求头的值用于解析token身份令牌
if(!headers.Authorization) headers.Authorization = 'xiaohe ' + token
// 返回请求头
return req
})
// 响应拦截
service.interceptors.response.use((res) => {
// 获取后端返回的code,data和提示语
const { code, data, msg } = res.data
if(code == 200) return data
else if(code === 50001) { // token认证失败
ElMessage.error(TOKEN_INVALID) // 给予5001的状态码
// 并且给予用户 一定的反应时间后,跳转登录页
setTimeout(() => {
router.push('/login')
}, 15000)
return Promise.reject(TOKEN_INVALID) // 抛出异常
} else {
// 丢出服务器异常
ElMessage.error(msg || NETWORK_ERROR)
return Promise.reject(msg || NETWORK_ERROR)
}
})
/**
* @param {*} options 请求配置
*/
function request(options: any) {
options.method = options.method || 'get'
if(options.method.toLowerCase() === 'get') options.params = options.data
if(typeof options.mock != 'undefined') config.mock = options.mock
if(config.env === 'prod') service.defaults.baseURL = config.baseApi
else service.defaults.baseURL = config.mock ? config.mockApi : config.baseApi
return service(options)
}
// 轮询接口类型,然后根据对应的类型,给予请求方式
['get', 'post', 'put', 'delete', 'patch'].forEach(item => {
request[item] = (url: string, data: any, options: string[]) => {
return request({ url, data, method: item, ...options })
}
})
// 丢出request
export default request
封装storage.ts
此处用到了storage和sessionStorage两种方法做缓存封装
/**
* 封装操作localstorage本地存储的方法
* @auther 何小玍。
* @date 2021/06/28
*/
export const storage = {
//存储
set(key: string, value: any) {
window.localStorage.setItem(key, JSON.stringify(value))
},
//取出数据
get<T>(key: string) {
const value = window.localStorage.getItem(key)
if (value && value != "undefined" && value != "null") return <T>JSON.parse(value)
else return "{}"
},
// 删除数据
remove(key: string) {
window.localStorage.removeItem(key)
}
};
/**
* 封装操作sessionStorage本地存储的方法
*/
export const sessionStorage = {
//存储
set(key: string, value: any) {
window.sessionStorage.setItem(key, JSON.stringify(value))
},
//取出数据
get<T>(key: string) {
const value = window.sessionStorage.getItem(key);
if (value && value != "undefined" && value != "null") return JSON.parse(value)
return null
},
// 删除数据
remove(key: string) {
window.sessionStorage.removeItem(key)
}
}
配置config.ts
在src目录下创建config文件夹,然后创建index.ts, 用于配置请求的基本配置参数和区分生产环境和开发环境
export interface IConfig {
env: string // 开发环境
mock?: boolean // mock数据
title: string // 项目title
baseApi?: string // api请求地址
mockApi?: string // mock地址
}
const dev: IConfig = {
env: "development",
mock: false,
title: "开发",
baseApi: "/api", // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
mockApi: "https://www.fastmock.site/mock/4f8c864d98d32e623e4a452a904ca70b/api"
}
const prod: IConfig = {
env: "production",
mock: false,
title: "生产",
baseApi: "https://www.baidu.com/api", // 正式api请求地址
mockApi: 'xxx'
}
export const config: IConfig = import.meta.env.MODE == 'development' ? dev : prod
配置api封装
在src目录下,创建api文件夹,然后生成user.ts文件,存放登录注册忘记密码等接口
import request from '../utils/request'
interface userState {
username: string
password: string
}
export default {
/**
* 登录接口
* @param { string } username 用户名称
* @param { string } password 用户密码
*/
login( data: userState ) {
return request({
url: '/users/login',
method: 'post',
data
})
}
}
配置router和路由守卫
在src文件夹下创建index.ts、router.config.ts
- 路由守卫的配置
import { createRouter, createWebHistory } from "vue-router"
import { constantRouterMap } from "./router.config"
import { useDocumentTitle } from "@/hooks/useDocumentTitle"
import store from "@/store"
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
// 在按下 后退/前进 按钮时,就会像浏览器的原生表现那样
scrollBehavior(to, from, savedPosition) {
if (savedPosition) return savedPosition
else return { top: 0 }
},
routes: constantRouterMap
})
// 路由开始进入
router.beforeEach((to: any, from: any, next) => {
useDocumentTitle(to.meta.title)
next()
return false
})
router.afterEach((to, from, next) => {
// 保存url
})
export default router
- 路由配置
import { RouteRecordRaw } from "./vue-router"
import Layout from '@/layout/index.vue'
export const constantRouterMap: Array<RouteRecordRaw> = [
{ path: '/login', name: 'login', component: () => import('@/views/login/login.vue'), meta: { title: '登录' }, hidden: true },
{ path: '/', name: '/', component: Layout, redirect: '/index', meta: { title: '博客', icon: 'el-icon-help' }, children: [
{ path: '/index', name: 'index', component: () => import('@/views/index/index.vue'), meta: { title: '博客', icon: 'el-icon-link' } }
] },
{ path: '/404', name: 'page404', component: () => import('@/views/404.vue'), meta: { title: '404' }, hidden: true },
{ path: '/:catchAll(.*)', redirect: '/404', hidden: true }
]
main.js配置
最后在main.js里面配置
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import svgIcon from './icons/index.vue'
import { storage, sessionStorage } from './utils/storage'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
// 引入全局样式
import "./styles/base.css"
import "./styles/reset.css"
const app = createApp(App)
app.config.globalProperties.storage = storage // 全局挂载 缓存方法
app.config.globalProperties.sessionStorage = sessionStorage // 全局挂载 缓存方法
app
.use(router)
.use(store)
.use(ElementPlus)
.component('svg-icon', svgIcon)
.mount('#app')
最后
公众号:小何成长,佛系更文,都是自己曾经踩过的坑或者是学到的东西
有兴趣的小伙伴欢迎关注我哦,我是:何小玍。大家一起进步鸭
猜你喜欢
- 2024-09-27 利用Vue中keep-alive,快速实现页面缓存
- 2024-09-27 vue i18n实现语言切换 vue怎么设置中文版本
- 2024-09-27 Node + Express + Mysql: Todo List项目让你成全栈
- 2024-09-27 vue仓库、组件间通信、前后台数据交互、前端储存数据大汇总
- 2024-09-27 多人群聊实现其实很简单:Nodejs+WebSocket+Vue轻松实现Web IM
- 2024-09-27 Todo List:Node+Express 搭建服务端连接Mysql - 第五章(第1节)
- 2024-09-27 推荐一个Vue3搭建的低代码数据可视化开发平台
- 2024-09-27 Vue认知及使用 vue了解
- 2024-09-27 Vue项目中实现用户登录及token验证
- 2024-09-27 Vue + Element UI 如何动态全局主题颜色?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)