1.config.js(用于网络请求的一些配置)
使用vite 在dev命令后面加上--mode 指定模式 后面可以通过获取
/**
* 环境配置封装
*/
//获取开发模式 如果没有则默认为production
const env = import.meta.env.MODE || 'production';
//根据获取到的开发模式决定采用哪一种配置
//每一个配置里面有上线api地址和mockApi地址
const EnvConfig = {
dev:{
baseApi:'http://localhost:3000/api',
mockApi:'https://www.fastmock.site/mock/c1c302e8baed9894c48c17e4738c092e/api'
},
test:{
baseApi:'/api',
mockApi:'https://www.fastmock.site/mock/c1c302e8baed9894c48c17e4738c092e/api'
},
production:{
baseApi:'/api',
mockApi:'https://www.fastmock.site/mock/c1c302e8baed9894c48c17e4738c092e/api'
}
}
export default {
//导出环境
env,
//是否mock的总开关
mock:false,
//命名空间 可以用来封装localStorage
namespace:'manger',
//导出api配置
...EnvConfig[env]
}
2.request.js 封装axios请求
/**
* axios二次封装
*/
import axios from 'axios'
//导入刚才设置的配置
import config from './../config'
import {ElMessage} from 'element-plus'
import router from '../router'
import storage from './storage'
//一些提示信息
const TOKEN_INVALID = 'Token认证失败,请重新登录'
const NETWORK_ERROR = '网络请求异常,请稍后重试'
const NETWORK_SUCCESS = '请求成功'
//axios创建示例对象 添加全局配置
const service = axios.create({
baseURL: config.baseApi,
timeout:8000
})
//请求拦截
service.interceptors.request.use((req)=>{
//获取http请求的请求头
const headers = req.headers;
//从本地存储中取出token
const {token} = storage.getItem('userInfo')
//要用jwt的话 就需要在每次请求的请求头加上token
if(!headers.Authorization) headers.Authorization = `Bearer ${token}`
return req;
})
//响应拦截
service.interceptors.response.use((res)=>{
const {code,data,msg} = res.data;
//正常状态码
if(code === 200){
if(msg=='登录成功'){
ElMessage.success(msg||NETWORK_SUCCESS)
}
return data;
//token认证失败
}else if(code === 50001){
ElMessage.error(TOKEN_INVALID)
//跳回登录页面
setTimeout(()=>{
router.replace('/login')
},15000)
return Promise.reject(TOKEN_INVALID)
}else{
// 网络错误或者别的错误
ElMessage.error(msg || NETWORK_ERROR)
return Promise.reject(NETWORK_ERROR)
}
})
/**
* 请求核心函数
* @param {*} options 请求配置
*/
function request(options){
//获取配置项里面的请求方法
options.method = options.method || 'get'
//如果是get请求 就把data赋值给params
if(options.method.toLowerCase() === 'get'){
options.params = options.data;
}
//如果某个请求的配置项有mock选项 就赋值给config的mock选项
if(typeof options.mock != 'undefined'){
config.mock = options.mock
}
//如果第一次请求传递了mock配置 第二次没传 那么config里面的默认配置就会失效 此处是修复这个bug
if(typeof options.mock == 'undefined'){
config.mock = false
}
//如果是生产环境
if(config.env === 'production'){
service.defaults.baseURL = config.baseApi
}else{
//如果是开发环境 就看mock开关是否打开
service.defaults.baseURL = config.mock ? config.mockApi:config.baseApi
}
return service(options)
}
//此处是为了 可以这样用 request.get/post...
['get','post','put','delete','patch'].forEach((item)=>{
//request['get']等于一个函数 这样就可以给request函数添加方法
request[item] = (url,data,options) => {
return request({
url,
data,
method:item,
...options
})
}
})
export default request
3.storage的封装
/**
* Storage二次封装
* @author JackBean
* @time 2021年10月19日
*/
//导入配置 为了里面的namespace变量
import config from "../config"
export default {
//存储设置
setItem(key,val){
//取出存储
let storage = this.getStorage();
//设置
storage[key] =val;
//在该命名空间下设置item
window.localStorage.setItem(config.namespace,JSON.stringify(storage))
},
//获取item
getItem(key){
return this.getStorage()[key]
},
//1.获取存储 如果此命名空间下有存储就取出 否则返回空对象
getStorage(){
return JSON.parse(window.localStorage.getItem(config.namespace) || "{}");
},
//清除某个item
clearItem(key){
let storage = this.getStorage();
delete storage[key]
window.localStorage.setItem(config.namespace,JSON.stringify(storage))
},
// 清除所有本地存储
clearAll(){
window.localStorage.clear()
}
}