这些都是我根据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>

小结

今天很开心

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐