Vue2项目练手——通用后台管理项目
- 数据的请求
- mock数据模拟实战
- 文件目录
- src/api/mock.js
- src/api/mockServeData/home.js
- main.js
- 首页组件布局
- 可视化图表
- 可视化图表布局
- Home.vue
- echarts表
- Home.vue
数据的请求
mock数据模拟实战
mock官方文档
前端用来模拟后端接口的工具,通过拦截前端发起的请求,自己定义一些数据
npm i mockjs
文件目录
src/api/mock.js
import Mock from 'mockjs'
import homeApi from "@/api/mockServeData/home";/*//定义请求拦截
Mock.mock('/api/home/getData',function (){//拦截到请求后处理的逻辑console.log("拦截到了")
})*/
//定义请求拦截
Mock.mock('/api/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 Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import router from "@/router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
import store from '@/store'
//引入mock模拟
import '@/api/mock'Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(ElementUI)
new Vue({store,router,render: h => h(App),
}).$mount('#app')
首页组件布局
可视化图表
可视化图表布局
Home.vue
<template><div><el-row><el-col :span="8" style="padding-right: 10px"><el-card class="box-card"><div class="user"><img src="@/assets/user.webp" alt=""><div class="userinfo"><p class="name">Admin</p><p class="access">超级管理员</p></div></div><div class="login-info"><p>上次登录的时间:<span>2023-08-30</span></p><p>上次登录的地点:<span>北京</span></p></div></el-card><el-card style="margin-top: 20px;height: 460px;"><el-table:data="tableData"style="width: 100%;"><el-table-column v-for="(val,key) in tableLabel" :prop="key" :label="val" /></el-table></el-card></el-col><el-col :span="16" style="padding-left: 10px"><div class="num"><el-card v-for="item in countData" :key="item.name" :body-style="{display:'flex',padding:0}"><i class="icon" :class="`el-icon-${item.icon}`" :style="{background:item.color}"></i><div class="detail"><p class="price">¥{{item.value}}</p><p class="desc">{{item.name}}</p></div></el-card></div><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></div></template><script>
import {getData} from "@/api";
export default {name: "Home",data(){return{tableData:[],tableLabel:{name:'课程',todayBuy:'今日购买',monthBuy:'本月购买',totalBuy:'总共购买'},countData:[{name: "今日支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},],}},mounted(){getData().then(({data})=>{console.log(data)// data.dataconst {tableData}=data.datathis.tableData=tableData})}
}
</script><style scoped lang="less">
.user{display: flex;align-items: center;padding-bottom: 20px;margin-bottom: 20px;border-bottom: 1px solid #ccc;img{margin-right: 40px;width: 150px;height: 150px;border-radius: 50%;}.userinfo{.name{font-size: 32px;margin-bottom: 10px;}.access{color: #999;}}
}
.login-info{p{line-height: 28px;font-size: 14px;color: #999;span{color: #666;margin-left: 60px;}}
}
.num{display: flex;flex-wrap: wrap;justify-content: space-between;.icon{width: 80px;height: 80px;color: #fff;line-height: 80px;text-align: center;font-size: 30px;}.detail{margin-left: 15px;display: flex;flex-direction: column;justify-content: center;.price{font-size: 30px;margin-bottom: 10px;line-height: 30px;}.desc{color: #999;font-size: 14px;text-align: center;}}.el-card{margin-bottom: 20px;width: 32%;}
}
.graph{display: flex;margin-top: 20px;justify-content: space-between;.el-card{width: 48%;}
}
</style>
echarts表
安装echarts
npm i echarts@5.1.2
Home.vue
- 折线图
mounted(){getData().then(({data})=>{console.log(data)// data.dataconst {tableData}=data.datathis.tableData=tableData//折线图// 基于准备好的dom,初始化echarts实例const echarts1 = echarts.init(this.$refs.echarts1)// 指定图表的配置项和数据var lineOption={}// 处理数据const {orderData,userData,videoData}=data.dataconst xAxis=orderData.dateconst xMore=Object.keys(orderData.data[0])lineOption.xAxis={data:xAxis}lineOption.yAxis={type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},}lineOption.legend={data:xMore}lineOption.tooltip={trigger:'axis'}lineOption.series=[]console.log(lineOption)xMore.forEach(key=>{lineOption.series.push({name:key,data:orderData.data.map(item=>item[key]),type:'line'})})// console.log(lineOption)// 使用刚指定的配置项和数据显示图表echarts1.setOption(lineOption)})}
<el-card style="height: 280px">
<!-- 折线图--><div ref="echarts1" style="height: 280px"></div></el-card>
- 柱状图:
<el-card style="height: 260px;">
<!-- 柱状图--><div ref="echarts2" style="height: 260px;"></div></el-card>
//柱状图const echarts2 = echarts.init(this.$refs.echarts2)var barOption={legend: {// 图例文字颜色textStyle: {color: "#333",},},grid: {left: "20%",},// 提示框tooltip: {trigger: "axis",},xAxis: {type: "category", // 类目轴data: userData.map(item=>item.date),axisLine: {lineStyle: {color: "#17b3a3",},},axisLabel: {interval: 0,color: "#333",},},yAxis: [{type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},},],color: ["#2ec7c9", "#b6a2de", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3"],series: [{name:"新增用户",data:userData.map(item=>item.new),type:'bar'},{name:"活跃用户",data:userData.map(item=>item.active),type:'bar'}],}echarts2.setOption(barOption)
- 饼状图
<el-card style="height: 260px;">
<!-- 饼状图--><div ref="echarts3" style="height: 240px"></div></el-card>
//饼状图const echarts3=echarts.init(this.$refs.echarts3)var pieOption = {tooltip: {trigger: "item",},color: ["#0f78f4","#dd536b","#9462e5","#a6a6a6","#e1bb22","#39c362","#3ed1cf",],series: [{data:videoData,type:'pie'}],}echarts3.setOption(pieOption)
全部代码:
<template><div><el-row><el-col :span="8" style="padding-right: 10px"><el-card class="box-card"><div class="user"><img src="@/assets/user.webp" alt=""><div class="userinfo"><p class="name">Admin</p><p class="access">超级管理员</p></div></div><div class="login-info"><p>上次登录的时间:<span>2023-08-30</span></p><p>上次登录的地点:<span>北京</span></p></div></el-card><el-card style="margin-top: 20px;height: 460px;"><el-table:data="tableData"style="width: 100%;"><el-table-column v-for="(val,key) in tableLabel" :prop="key" :label="val" /></el-table></el-card></el-col><el-col :span="16" style="padding-left: 10px"><div class="num"><el-card v-for="item in countData" :key="item.name" :body-style="{display:'flex',padding:0}"><i class="icon" :class="`el-icon-${item.icon}`" :style="{background:item.color}"></i><div class="detail"><p class="price">¥{{item.value}}</p><p class="desc">{{item.name}}</p></div></el-card></div><el-card style="height: 280px">
<!-- 折线图--><div ref="echarts1" style="height: 280px"></div></el-card><div class="graph"><el-card style="height: 260px;">
<!-- 柱状图--><div ref="echarts2" style="height: 260px;"></div></el-card><el-card style="height: 260px;">
<!-- 饼状图--><div ref="echarts3" style="height: 240px"></div></el-card></div></el-col></el-row></div></template><script>
import {getData} from "@/api";
import * as echarts from 'echarts'
export default {name: "Home",data(){return{tableData:[],tableLabel:{name:'课程',todayBuy:'今日购买',monthBuy:'本月购买',totalBuy:'总共购买'},countData:[{name: "今日支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},],}},mounted(){getData().then(({data})=>{console.log(data)// data.dataconst {tableData}=data.datathis.tableData=tableData// 基于准备好的dom,初始化echarts实例const echarts1 = echarts.init(this.$refs.echarts1)// 指定图表的配置项和数据var lineOption={}// 处理数据const {orderData,userData,videoData}=data.dataconst xAxis=orderData.dateconst xMore=Object.keys(orderData.data[0])lineOption.xAxis={data:xAxis}lineOption.yAxis={type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},}lineOption.legend={data:xMore}lineOption.tooltip={trigger:'axis'}lineOption.series=[]console.log(lineOption)xMore.forEach(key=>{lineOption.series.push({name:key,data:orderData.data.map(item=>item[key]),type:'line'})})// console.log(lineOption)// 使用刚指定的配置项和数据显示图表echarts1.setOption(lineOption)//柱状图const echarts2 = echarts.init(this.$refs.echarts2)var barOption={legend: {// 图例文字颜色textStyle: {color: "#333",},},grid: {left: "20%",},// 提示框tooltip: {trigger: "axis",},xAxis: {type: "category", // 类目轴data: userData.map(item=>item.date),axisLine: {lineStyle: {color: "#17b3a3",},},axisLabel: {interval: 0,color: "#333",},},yAxis: [{type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},},],color: ["#2ec7c9", "#b6a2de", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3"],series: [{name:"新增用户",data:userData.map(item=>item.new),type:'bar'},{name:"活跃用户",data:userData.map(item=>item.active),type:'bar'}],}echarts2.setOption(barOption)//饼状图const echarts3=echarts.init(this.$refs.echarts3)var pieOption = {tooltip: {trigger: "item",},color: ["#0f78f4","#dd536b","#9462e5","#a6a6a6","#e1bb22","#39c362","#3ed1cf",],series: [{data:videoData,type:'pie'}],}echarts3.setOption(pieOption)})}
}
</script><style scoped lang="less">
.user{display: flex;align-items: center;padding-bottom: 20px;margin-bottom: 20px;border-bottom: 1px solid #ccc;img{margin-right: 40px;width: 150px;height: 150px;border-radius: 50%;}.userinfo{.name{font-size: 32px;margin-bottom: 10px;}.access{color: #999;}}
}
.login-info{p{line-height: 28px;font-size: 14px;color: #999;span{color: #666;margin-left: 60px;}}
}
.num{display: flex;flex-wrap: wrap;justify-content: space-between;.icon{width: 80px;height: 80px;color: #fff;line-height: 80px;text-align: center;font-size: 30px;}.detail{margin-left: 15px;display: flex;flex-direction: column;justify-content: center;.price{font-size: 30px;margin-bottom: 10px;line-height: 30px;}.desc{color: #999;font-size: 14px;text-align: center;}}.el-card{margin-bottom: 20px;width: 32%;}
}
.graph{display: flex;margin-top: 20px;justify-content: space-between;.el-card{width: 48%;}
}
</style>