Vue项目Axios+Mock使用
Vue项目Axios+Mock使用
这些都是我根据B站winWeb前端分享的个人空间_哔哩哔哩_Bilibili 的视频再自己动手进行实践的
在Web应用的实际开发过程中,前后端的开发往往是同时进行的,而前端大量的动态页面和用户交互,无不需要数据的支持。因此,我们可以根据数据的接口文档来模拟一部分数据来测试前端的功能,这时候我们可以使用mock.js这一工具来拦截http请求,并根据接口文档来模拟我们测试所需要的数据再返回,以供前端的开发和调试。
而Axios是对Ajax异步请求的一个封装库,可以更加方便的使用异步请求的方式来获取数据。
Mock.js的安装和使用
首先我们使用命令安装mockjs
# npm
npm install mockjs -S
# yarn
yarn add mockjs -S
然后在src目录下构建模拟的用户接口目录(api),在其中添加模拟的数据仓库(mockData),我这里使用js来保存数据(实际开发中数据格式往往是json),下面是模拟的两个数据对象:
//本地mock模拟数据
export default {
getHomeData:()=>{
return {
code: 200,
data: [{
name:"oppo",
todayBuy: 500,
monthBuy: 3500,
totalBuy: 22000
},
{
name:"vivo",
todayBuy: 300,
monthBuy: 2200,
totalBuy: 24000
},
{
name:"苹果",
todayBuy: 800,
monthBuy: 4500,
totalBuy: 65000
},
{
name:"小米",
todayBuy: 1200,
monthBuy: 6500,
totalBuy: 45000
},
{
name:"三星",
todayBuy: 300,
monthBuy: 2000,
totalBuy: 34000
},
{
name:"魅族",
todayBuy: 350,
monthBuy: 3000,
totalBuy: 22000
},
]
}
},
getCountData:()=>{
return {
code: 200,
data: [{
name:"今日支付订单",
value: 1234,
icon: "SuccessFilled",
color: "#2ec7c9"
},
{
name:"今日收藏订单",
value: 210,
icon: "StarFilled",
color: "#ffb980"
},
{
name:"今日未支付订单",
value: 1234,
icon: "GoodsFilled",
color: "#5ab1ef"
},
{
name:"本月支付订单",
value: 1234,
icon: "SuccessFilled",
color: "#2ec7c9"
},
{
name:"本月收藏订单",
value: 210,
icon: "StarFilled",
color: "#ffb980"
},
{
name:"本月未支付订单",
value: 1234,
icon: "GoodsFilled",
color: "#5ab1ef"
},
]
}
}
}
在api目录下拦截mock请求,新建mock.js
import Mock from 'mockjs'
import hmoeApi from './mockData/home.js'
//拦截请求
Mock.mock('/home/getData',hmoeApi.getHomeData);
Mock.mock('/home/getCount',hmoeApi.getCountData);
然后在main.js中导入mock.js即可在vue页面中使用了
...
import './api/mock.js'
const app = createApp(App);
...
app.mount('#app');
在此实际上本地mock已经配置完成了,只要页面发送了'/home/getData'或'/home/getCount'请求就会被mock拦截,为了验证mock的功能此时我们需要页面发送请求。
使用Axios发送异步请求
首先我们需要安装Axios,使用命令
# npm
npm install mockjs -S
# yarn
yarn add mockjs -S
安装完成后在Home.vue中进行使用,下面是在Home.vue中的script,在里面进行发出axios请求来获取数据。
<script>
import {defineComponent,onMounted,ref} from 'vue'
import axios from 'axios'
export default defineComponent({
setup() {
let tableData=ref([]); //直接导入数据会不会成功需要引入ref初始化
let countData=ref([]);
const tableHeader={
name:'课程',
todayBuy: '今日销量',
monthBuy: '本月销量',
totalBuy: '总销量',
};
const getTableList=async()=>{
await axios.get("/hmoe/getData").then((res)=>{
console.log(res);
if(res.data.code == 200) {
tableData.value=res.data.data;
}
});
tableData.value=res;
}
const getCountList=async()=>{
await axios.get("/hmoe/getCount").then((res)=>{
console.log(res);
if(res.data.code == 200) {
countData.value=res.data.data;
}
});
countData.value=res;
}
onMounted(()=>{
getTableList(),
getCountList()
})
return {
tableHeader,
tableData,
countData
}
}
})
</script>
之后我们就可以在html中绑定数据进行使用了:
<template>
<el-row class="home" :gutter="20">
<el-col :span="8" style="margin-top:20px">
<el-card shadow="hover">
<div class="user">
<img src="../../assets/img/user.jpg" alt="">
<div class="user-info">
<p class="name">Admin</p>
<p class="role">超管</p>
</div>
</div>
<div class="login-info">
<p>上次登录时间:<span>2022-7-21</span></p>
<p>上次登录地点:<span>北京</span></p>
</div>
</el-card>
<el-card shadow="hover" style="margin-top:20px" height="450px">
<el-table :data="tableData">
<el-table-column
v-for="(item, index) in tableHeader"
:key="index"
:prop="index"
:label="item"
>
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="16" style="margin-top:20px">
<div class="count-num">
<el-card
shadow="hover"
:body-style="{display:'flex',padding:0}"
v-for="item in countData"
>
<component
class="icons"
:is="item.icon"
:style="{background:item.color}"
></component>
<div class="count-detail">
<p class="number">¥{{item.value}}</p>
<p class="text">{{item.name}}</p>
</div>
</el-card>
</div>
</el-col>
</el-row>
</template>
下面是运行的效果图:
二次封装Axios
首先我们为什么要对Axios再进行封装,因为往往我们的项目会越做越大,页面也会越来越多,随之而来的是接口数量的增加,那么二次封装Axios,实现api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护。
首先我们在api目录下新建api.js来管理整个项目的api:
/**
* 整个项目Api的管理
*
*/
import request from "./request"
export default {
// home组件,左侧表格数据获取
getTableData(params) {
return request({
url:'/home/getData',
method: 'get',
data: params,
mock: true
})
},
getCountData() {
return request({
url:'/home/getCount',
method: 'get',
mock: true
})
},
}
考虑到我们实际进行企业级开发的过程中存在三种运行环境,我们需要根据环境来确认是使用mock响应请求还是真实的让后端来响应请求,所以我们在src目录下新建一个配置文件/config/index.js,其源代码如下:
/**
* 环境配置文件
* 一般在企业级项目中有三个环境
* 开发环境
* 测试环境
* 线上环境
*/
//取当前环境,取不到默认为线上环境
const env = import.meta.env.MODE || 'prod'
const EnvConfig={
development:{
baseApi:'/api',
mockApi:''
},
test:{
baseApi:'//test.future.com/api',
mockApi:'https://www.fastmock.site/mock/300283cb590d2022f75682f11a1848b0/api'
},
pro:{
baseApi:'//future.com/api',
mockApi:'https://www.fastmock.site/mock/300283cb590d2022f75682f11a1848b0/api'
}
}
export default {
env,
//mock的总开关
mock: true,
...EnvConfig[env]
}
随后我们进行Axios的封装,比如我们需要对请求进行一些预处理,或者在请求结束之后对请求的状态码进行检查和参数的检查等等,下面是封装源代码request.js:
//二次封装axios
import axios from "axios";
import config from '../config'
import { ElMessage } from "element-plus";
const NETWORK_ERROR = "网络请求异常,请稍后重试"
// 创建axios 实例对象
const service = axios.create({
baseURL:config.baseApi
})
// 在请求前预处理
service.interceptors.request.use((req)=>{
//console.log(req);
// 自定义header
// jwt-token认证
return req
})
// 请求后统一处理
service.interceptors.response.use((res)=>{
//console.log(res);
const {code,data,msg} = res.data
// 根据前后端协商而定
if(code==200) {
return data
} else {
//请求失败
ElMessage.error(msg || NETWORK_ERROR)
return Promise.reject(msg || NETWORK_ERROR)
}
})
// 封装核心函数
// 传入参数如api.js中的形式
function request(options) {
//console.log(options);
// 请求默认get请求
options.method = options.method || 'get';
if(options.method.toLowerCase() == 'get') {
options.params=options.data
}
// 处理mock
let isMock = config.mock
if(typeof options.mock !== 'undefined'){
// 在传入了自定义的mock请求时使用自定义的mock
isMock=options.mock
}
// 处理线上环境
if(config.env == 'prod') {
// 如果是线上环境禁用mock
service.defaults.baseURL = config.baseApi
}
else {
service.defaults.baseURL = isMock?config.mockApi:config.baseApi;
}
return service(options);
}
export default request;
之后我们就需要去main.js中进行挂载:
import { createApp } from 'vue'
...
import api from './api/api'
const app = createApp(App);
...
app.config.globalProperties.$api = api //全局挂载APi
app.mount('#app');
挂载完成后就可以在vue中进行使用了,此时我们实际使用就完全基于api.js中声明的接口进行使用,统一了接口的管理,下面是使用的部分源代码:
<script>
import {defineComponent,getCurrentInstance,onMounted,ref} from 'vue'
import axios from 'axios'
export default defineComponent({
setup() {
const {proxy} = getCurrentInstance();
let tableData=ref([]); //直接导入数据会不会成功需要引入ref初始化
let countData=ref([]);
const tableHeader={
name:'课程',
todayBuy: '今日销量',
monthBuy: '本月销量',
totalBuy: '总销量',
};
const getTableList=async()=>{
let res = await proxy.$api.getTableData(); //使用api.js中声明的方法发送请求
tableData.value=res;
}
const getCountList=async()=>{
let res = await proxy.$api.getCountData();
countData.value=res;
}
onMounted(()=>{
getTableList(),
getCountList()
})
return {
tableHeader,
tableData,
countData
}
}
})
</script>
小结
今天很开心
更多推荐
所有评论(0)