1. axios
axios官方文档
异步库axios和mockjs模拟后端数据,axios是一个基于promise的HTTP库,使用npm i axios。在main.js中引入,需要绑定在Vue的prototype属性上,并重命名。
(1)main.js文件引用
import http from 'axios'
Vue.prototype.$http = http
1.1. axios简单例子
(1)在home的index.vue中添加mounted
/*** 拦截器部分* @param instance*/interceptors(instance) {// 添加请求拦截器instance.interceptors.request.use(function (response) {console.log("添加请求拦截器:", response)// 在发送前做什么return response;}, function (error) {// 对请求错误做什么console.log("error错误:", error)return Promise.reject(error);});// 添加响应拦截器instance.interceptors.response.use(function (response) {// 对响应数据前做什么console.log("添加请求拦截器2:", response)return response;}, function (error) {console.log("error错误2:", error)// 响应错误后做什么return Promise.reject(error);});}
在控制台中可以发现请求已发送,状态为404
1.2. axios函数封装
(1)在src目录下新建config文件夹,新建index.js,主要是让系统判断当前处于生产状态还是用户状态。
//src/api/index.js
export default{baseUrl:{dev:'/api/',//开发环境pro:''//生产环境}
}
(2)对axios函数进行二尺封装,方便后续使用。在根目录下新建api文件夹,新建axios.js文件。
//src/api/axios.js
import axios from 'axios'
import config from '../config'
// 将config和anios进行有机结合,对axios进行简单封装。
// 判断是不是生产环境,并拿到config中的dev环境,否则拿到config中的pro环境。
const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro
/*** axios工具类,工具类拿到对应的url后,进行相应配置*/
class HttpRequest {constructor (baseUrl) {this.baseUrl = baseUrl}/*** 用于定义anios的相关配置的方法* @returns {{header: {}, base: *}}*/getInsideConfig(){const config = {base:this.baseUrl,header:{}}return config}/*** 拦截器部分* @param instance*/interceptors (instance) {// 添加请求拦截器instance.interceptors.request.use(function(config){// 在发送前做什么return config;},function (error){// 对请求错误做什么return Promise.reject(error);});// 添加响应拦截器instance.interceptors.response.use(function(response){// 对响应数据前做什么return response;},function(error){// 响应错误后做什么return Promise.reject(error);});}/*** 接口请求* @param options* @returns {*}*/request(options){//创建axios实例const instance = axios.create()// ES6语法解构,三点表示解构options = {...this.getInsideConfig(), ...options}// 调用拦截器this.interceptors(instance)return instance(options)}
}export default new HttpRequest(baseUrl)
1.3. 接口调用
(1)在src/api下新建data.js文件,用于添加网络接口
//src/api/data.js
// 这里引入的是文件,不是依赖
import axios from './axios'
/*** 接口对外暴露* @param param* @returns {*}*/
export const getMenu = (param) => {return axios.request({url:'/permission/getMenu',method:'post',data:param})
}
(2)在src/views/home/index.vue中调用
//src/views/home/index.vuemounted() {// //接口请求一般在mounted下// const axios = require('axios');// // 上述请求也可以按以下方式完成(可选)// axios.get('/user', {// params: {// ID: 12345// }// }).then(function (response) {// console.log(response);// })// .catch(function (error) {// console.log(error);// })// .finally(function () {// // 总是会执行// });getMenu().then(res => {console.log("post==",res)})}
//src/views/home/index.vue
<template><el-row class="home" :gutter="20" style="height:100vh;"><!--用户布局--><el-col :span="9" class="user-section"><el-card shadow="hover"><div class="user-layout"><img class="user-header" :src="userImg"/><div class="user-info-layout"><p class="user-name">Admin</p><p class="user-nickname">超级管理员</p></div></div><div class="login-layout"><p class="login-time">上次登录时间:<span>2024-12-12</span></p><p class="login-loc">上次登录地点:<span>济南</span></p></div></el-card><!--列表展示--><el-card class="list-section"><el-table :data="tableData"><el-table-columnv-for="(val,key) in tableLabel":key="key":prop="key":label="val"></el-table-column></el-table></el-card></el-col><!--右侧布局--><el-col :span="15"><!--订单统计--><el-col :span="8" v-for="(item) in countData":key="item.name" :offset="0"><el-card class="order-section":body-style="{display:'flex', padding:0}"><div class="order-layout"><i class="order-icon" :class="'el-icon-'+item.icon":style="{background:item.color}"></i><div class="order-detail"><p class="order-num">¥{{item.value}}</p><p class="order-title">{{item.name}}</p></div></div></el-card></el-col><el-card style="height:280px;"></el-card><div class="graph"><el-card style="height:260px;"></el-card><el-card style="height:260px;"></el-card></div></el-col></el-row>
</template><script>import {getMenu} from '../../api/data.js'export default {name: "home",data() {return {userImg: require("../../assets/images/user.png"),tableData: [{name: "华为",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "荣耀",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "oppo",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "vivo",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "苹果",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "小米",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "三星",todayBuy: 100,monthBuy: 300,totalBuy: 800,},{name: "魅族",todayBuy: 100,monthBuy: 300,totalBuy: 800,}],tableLabel: {name: '课程',todayBuy: '今日购买',monthBuy: '本月购买',totalBuy: '总购买',},countData: [{name: "今日支付订单",value: 1234,icon: "success",color: "#2ec7c9",offset: 0,},{name: "今日收藏订单",value: 210,icon: "star-on",color: "#ffb980",offset: 1,},{name: "今日未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",offset: 2,},{name: "本月支付订单",value: 1234,icon: "s-home",color: "#fbcc00",offset: 0,},{name: "本月收藏订单",value: 210,icon: "s-cooperation",color: "#ff4444",offset: 1,},{name: "本月未支付订单",value: 1234,icon: "s-shop",color: "#33cc87",offset: 2,},]}},mounted() {// //接口请求一般在mounted下// const axios = require('axios');// // 上述请求也可以按以下方式完成(可选)// axios.get('/user', {// params: {// ID: 12345// }// }).then(function (response) {// console.log(response);// })// .catch(function (error) {// console.log(error);// })// .finally(function () {// // 总是会执行// });getMenu().then(res => {console.log("post==",res)})}}
</script>
<style lang="less">/*用户模块*/.user-section {margin: 10px 0}.user-layout {display: flex;flex-direction: row;align-items: center;border-bottom: #999 solid 1px;padding: 0 10px 10px;}.user-header {width: 100px;height: 100px;border-radius: 50%;}.user-info-layout {display: flex;flex-direction: column;margin-left: 20px;}.user-name {font-size: 18px;color: black;font-weight: 700;}.user-nickname {font-size: 18px;color: black;margin-top: 5px;font-weight: 700;}.login-layout {display: flex;flex-direction: column;margin-left: 20px;}.login-time {font-size: 17px;color: black;margin-top: 5px;}.login-loc {font-size: 17px;color: black;margin-top: 8px;}/*列表展示*/.list-section {margin-top: 20px;height: 460px;}/*订单统计*/.order-section {padding: 0 0;margin: 10px 0 15px;background-color: white;}.order-layout {display: flex;flex-direction: row;align-items: center;}.order-icon {display: flex;width: 65px;height: 65px;//border-radius: 50%;align-items: center;justify-content: center;}.order-detail {display: flex;flex-direction: column;justify-content: center;margin-left: 15px;}.order-num {color: #333333;font-size: 18px;}.order-title {color: #333;font-size: 18px;font-weight: 700;margin-top: 8px;}</style>
 axios网络请求示例下载
1.4. 对响应拦截器进行更改
对/src/api/index.js下的拦截器进行更改,打印拦截数据。
/*** 拦截器部分* @param instance*/interceptors(instance) {// 添加请求拦截器instance.interceptors.request.use(function (response) {console.log("添加请求拦截器:", response)// 在发送前做什么return response;}, function (error) {// 对请求错误做什么return Promise.reject(error);});// 添加响应拦截器instance.interceptors.response.use(function (response) {// 对响应数据前做什么return response;}, function (error) {// 响应错误后做什么return Promise.reject(error);});}
1.5. mockjs使用
官方文档
mock可以拦截ajax请求,在mock的回调函数中返回接口的响应数据。可以模拟后端发送过来的接口数据。mock可以使用数据模板生成数据。
在api下新建mock.js,先npm i mockjs。Mock.mock(url,回调函数),这里模块化编程,提前准备好数据模板,在api下新建mockServeData文件夹,新建home.js文件,存放home页面下的mock的模拟数据。
//src/api/mock.js
import Mock from 'mockjs'
import homeApi from './mockServeData/home.js'
Mock.mock('/home/getData',homeApi.getStatisticalData)
//src/api/mockServeData/home.js
// mock数据模拟
import Mock from 'mockjs'// 图表数据
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: [{name: '小米',value: 2999},{name: '苹果',value: 5999},{name: 'vivo',value: 1500},{name: 'oppo',value: 1999},{name: '魅族',value: 2200},{name: '三星',value: 4500}],// 柱状图userData: [{date: '周一',new: 5,active: 200},{date: '周二',new: 10,active: 500},{date: '周三',new: 12,active: 550},{date: '周四',new: 60,active: 800},{date: '周五',new: 65,active: 550},{date: '周六',new: 53,active: 770},{date: '周日',new: 33,active: 170}],// 折线图orderData: {date: ['20191001', '20191002', '20191003', '20191004', '20191005', '20191006', '20191007'],data: List},tableData: [{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}]}}}
}
在main.js中引入import ‘./api/mock.js’。
在src/views/home下index.vue中引入getData。import { getData } from ‘…/…/api/data.js’,并暴露使用。
//src/views/home/index.jsmounted(){getData().then(res => {console.log(res)})}
在api中data.js中编写getData,这里没有写请求类型,默认是get请求。
//data.js
export const getData = () =>{return axios.request({url:'/home/getData'})
}
url为:
接口拦截成功,并返回数据。
将数据进行解构
对home的index.vue的mounted进行修改,并将return中的tableData定义为空数组,tableData:[]。
mounted(){getData().then(res => {const { code,data } = res.dataif (code === 20000){this.tableData = data.tableData}console.log(res)})}
前后数据区别:一个是原本写死的数据,一个是模拟后端的mock数据。
VueWeb Mock示例下载