Axios
使用流程
1 安装
npm install axios --save
2 配置与封装
有时候我们开发的时候服务器前面的baseUrl时重复的,这时候我们想要修改url的话就会很麻烦,我们直接全局配置baseurl
当在前后端一起联调的时候,如果更换了局域网,我们在多个组件内不需要一个个更改,而是在main.js中修改baseURL就可以了。
例子:
配置
service/request/config.js
const baseURL = "http://123.207.32.32:1888/api";
const TIMEOUT = 50000;
export { baseURL, TIMEOUT };
封装
service/request/index.js
import axios from "axios";
import { useLoadingStore } from "@/stores/modules/loading";
import { baseURL, TIMEOUT } from "./config"; //引入上面的配置
import useMainStore from "../../stores/modules/main";
import { storeToRefs } from "pinia";
const loadingStore = useLoadingStore();
const mainStore = useMainStore()
// const {isLoading} = storeToRefs(mainStore)
class MyRequest {
constructor(baseURL) {
//创建一个axios实例
this.instance = axios.create({
baseURL,
timeout: TIMEOUT,
});
//请求拦截器:在请求发送前进行必要操作处理
this.instance.interceptors.request.use(function (config) {
//拦截下来的是这个请求的所有配置,发送成功但是被拦截了
// 在发送请求之前做些什么
mainStore.isLoading = true
//返回这个请求的配置
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 响应拦截器:请求得到响应之后,对响应体的一些处理
this.instance.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据成功做点什么
mainStore.isLoading = false
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
mainStore.isLoading = false
return Promise.reject(error);
});
}
//当响应拦截之后,axios就不能请求到数据了 打印出来是undefined
//拦截完数据后,可以返回出我想要的数据
//比如说我只要拿到data数据,就可以return res.data
//request get post 都是axios里自带的方法,下面不配置也行(?)
request(config) {
loadingStore.changeLoading(true);
return new Promise((resolve, reject) => {
this.instance
.request(config)
.then((res) => {
resolve(res.data);
})
.catch((err) => {
console.log("request err:", err);
reject(err);
})
.finally(() => {
loadingStore.changeLoading(false);
});
});
}
get(config) {
return this.request({ ...config, method: "get" });
}
post(config) {
return this.request({ ...config, method: "post" });
}
}
export default new MyRequest(baseURL);
参考:网络请求axios与request、数据管理store与pinia、各种封装
网络请求数据
我们用封装好的网络请求库来请求数据。
注意:
- request中的index导出的是一个对象(
new MyRequest()
) - MyRequest.get的参数是对象(
...config
)
一般来说,到这里我们就可以利用封装好的axios从接口文档请求相应的数据了,但开发过程中可能会遇到后端暂时还未提供接口的情况,这时我们可以用Mock.js来模拟数据,拦截axios请求,进行测试
下面来详细介绍这两种情况请求数据的具体过程
1 通过接口文档获取数据
(1)按模块封装网络请求操作
service/modules/city.js
// 此文件保存所有city页面的网络请求
import HYRequest from '@/service/request'
export default function getAllCity() {
// request的index导出的是一个对象
return HYRequest.get({
// 参数也是一个对象
url: '/city/all'
})
}
getAllCity()
我们在service文件夹下新建index.js,里面保存所有会被使用的service:导出所有导入的模块。
// 此文件导入并导出所有要使用的service
export * from '@/service/modules/city'
(2)在store中统一按模块保存管理
我们把请求到的数据和对数据的处理封装到一个文件里,把处理好的数据导出。在vue的页面中只需要直接使用处理好的数据即可。
stores/modules/city.js
// city.vue页面所有的进行网络请求和数据都封装到这里
import { getAllCity } from "@/service";
import { defineStore } from "pinia";
const useCityStore = defineStore('city', {
state: () => {
return {
allCity: {}
}
},
actions: {
// 调用网络请求
async fetchAllCity() {
const res = await getAllCity()
this.allCity = res.data
}
}
})
export default useCityStore
(3)在vue组件中获取请求回来的数据
const cityStore=useCityStore()
cityStore.fetchAllCity()
// cityStore是响应式的
const { allCity } = storeToRefs(cityStore)
console.log(allCity)
2 通过mock.js数据
mock
(1) 安装:
npm install mockjs
(2) 封装axios请求操作
service/index.js
//部分
import MyRequest from '@/service/request'
export const getData = () => {
return MyRequest.get("/home/getData")
}
export const getUser = (params) => {
return MyRequest.get('/user/get', params)
}
export const createUser = (data) => {
return MyRequest.post('/user/create', data)
}
(3)Mock模拟数据
import Mock from "mockjs"
//引入一些本地数据
import tableData from "@/data/tableData"
import userData from "@/data/userData"
import videoData from '@/data/videoData'
let List = []
export default{
getStatisticalData: () => {
//Mock.Random.float 产生随机数100到8000之间 保留小数 最小0位 最大0位
for (let i = 0; i < 7; i++) {
List.push(
Mock.mock({
苹果: Mock.Random.float(100, 8000, 0, 0),
vivo: Mock.Random.float(100, 8000, 0, 0),
oppo: Mock.Random.float(100, 8000, 0, 0),
魅族: Mock.Random.float(100, 8000, 0, 0),
三星: Mock.Random.float(100, 8000, 0, 0),
小米: Mock.Random.float(100, 8000, 0, 0)
})
)
}
// 返回给浏览器的数据
return {
code: 20000,
data: {
// 饼图
videoData,
// 柱状图
userData,
// 折线图
orderData: {
date: ['20191001', '20191002', '20191003', '20191004', '20191005', '20191006', '20191007'],
data: List
},
tableData
}
}
}
}
(4)定义Mock拦截
mock.js
// 引入测试数据 home
import Mock from 'mockjs'
import homeApi from './mockData/home'
import user from './mockData/user'
import permission from './mockData/permission'
Mock.mock('/api/home/getData', homeApi.getStatisticalData)
// Mock.mock('/\api\/user\/get', user.getUserList)
Mock.mock(/api\/user\/get/,user.getUserList) //正则匹配
// Mock.mock('/api/user/create', "post", user.createUser)
Mock.mock('/api/user/create','post',user.createUser)
Mock.mock('/api/user/del', "post", user.deleteUser)
Mock.mock('/api/user/update', "post", user.updateUser)
Mock.mock(/api\/permission\/getMenu/, 'post', permission.getMenu)//正则匹配
// 登录权限
// Mock.mock(/api\/permission\/getMenu/,'post',permission.getMenu)
main.js里引入该文件
import '@/service/mock'
(5)在vue中获取数据
import { getData} from '../api/index'
export default {
data(){
return{
purchaseData,
TableLabel,
tableData: []
}
},
created(){
getData().then((data)=>{
console.log(data);
this.tableData = data.data.data.tableData
})
}
}