本博客内容参考黑马课程,详细信息请参考以下网址
- Bilibili官方黑马课程:【echarts数据可视化项目】
前端
效果展示
项目架构
Seller.vue
该部分主要实现业务逻辑,即决定/sellerpage的内容到底是什么样子的
<template>
<!-- 商家销量统计柱状图 -->
<div class="com-container">
<div class="com-chart" ref="chart_area"></div>
</div>
</template>
<script>
export default {
name: "Seller",
data() {
return {
chartInstance: null,
allData: null,
};
},
mounted() {
this.initChart();
this.getData();
},
methods: {
//初始化图表,生成chartInstance对象
initChart() {
this.chartInstance = this.$echarts.init(this.$refs.chart_area);
},
//向后端获取数据并调用updatechart()进行图表更新
async getData() {
//异步请求获得数据
const ret = await this.$http.get("seller");
//获取数组
this.allData = ret.data.data;
//更新图表
this.updateChart();
},
//配置echarts图标的option配置项,并调用setOption()函数进行配置
updateChart() {
//利用map函数分别提取出原数组中的姓名和value值
const sellerName = this.allData.map((item) => {
return item.name;
});
const sellerValue = this.allData.map((item) => {
return item.value;
});
// console.log(sellerName, sellerValue);
const option = {
tooltip: {},
xAxis: {
type: "value",
},
yAxis: {
type: "category",
data: sellerName,
},
series: [
{
type: "bar",
data: sellerValue,
},
],
};
this.chartInstance.setOption(option);
},
},
};
</script>
SellerPage.vue
主要业务逻辑由子组件Seller.vue实现,该组件只关心/sellerpage路由的配置和现实问题
<template>
<!-- 针对/sellerage路径而显示,在该组件中通过子组件注册
来显示Seller.vue -->
<div class="com-page">
<seller></seller>
</div>
</template>
<script>
import Seller from "../components/Seller.vue";
export default {
name: "SellerPage",
data() {
return {};
},
methods: {},
components: {
seller: Seller,
},
};
</script>
<style></style>
index.js
该文件主要内容是实例化一个VueRouter对象并向外暴露,供main.js引入配置。该文件需要将所有的路由组件引入并配置在VueRouter实例对象中
import Vue from "vue";
import VueRouter from "vue-router";
//引入单文件路由组件
import SellerPage from "@/views/SellerPage.vue";
Vue.use(VueRouter);
//设置VueRouter的路由配置项
const routes = [
{
path: "/sellerpage",
component: SellerPage,
},
];
//创建VueRouter实例对象
const router = new VueRouter({
routes,
});
//向外暴露
export default router;
App.vue
由于本案例仅仅配置了一个路由:/sellerpage,项目运行后,localhost:8080/#/下并没有内容,localhost:8080/#/sellerpage路径下才显示图表,所以App.vue文件比较简单,只配置了<router-view>标签
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
import Vue from "vue";
var vm = new Vue({
name: "App",
});
export default vm;
</script>
main.js
项目的入口文件,主要内容是要生成一个Vue实例对象挂载到DOM元素上、同时要引入路由文件,并配置在Vue实例对象中。还有其他文件的引入和挂载
import Vue from "vue";
import App from "./App.vue";
//引入路由文件
import router from "./router";
import VueRouter from "vue-router";
//引入axios
import axios from "axios";
//引入样式文件
import "./assets/css/global.less";
//设置异步请求根目录
axios.defaults.baseURL = "http://127.0.0.1:8888/";
//将axios和echarts挂载到Vue原型对象上
Vue.prototype.$http = axios;
Vue.prototype.$echarts = window.echarts;
//关闭生产提示
Vue.config.productionTip = false;
//使用VueRouter插件
Vue.use(VueRouter);
//实例化Vue对象
new Vue({
render: (h) => h(App),
router: router,
}).$mount("#app");
- 模块安装(切换到项目目录)
vue-router:npm i vue-router@3
axios:npm i axios
less:npm install less less-loader --save-dev
若不安装less就使用将会报错:Module not found: Error: Can’t resolve ‘less-loader’
index.html
该文件主要设置了一个div容器用于挂载Vue实例对象,同时引入了echarts的js文件,这样在window下就有了一个全局echarts对象
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.1/echarts.min.js"></script>
</html>
后端
本案例后端由python的Flask库完成,主要作用是为前端提供一个接口以获得图表数据
源程序
from flask import Flask
import json
import random
from flask_cors import CORS
app = Flask(__name__)
# 用于配置跨域,防止前端报出跨域错误
CORS(app, resources=r'/*')
# 该函数返回随机数组,每个数组元素都是一个字典,每个字典包括name和value两个属性
def get_seller_info():
first_name = ['张', '王', '李', '赵']
last_name = ['三', '颜', '明', '栋', '超', '月']
info_list = []
for i in range(15):
name = random.choice(first_name) + random.choice(last_name)
value = random.randint(500, 9999)
info_list.append({'name': name, 'value': value})
return info_list
@app.route("/seller", methods=["GET"])
def return_seller_data():
seller_info = get_seller_info()
return_dict = {'return_code': '200',
'return_info': '处理成功',
'data': seller_info}
return json.dumps(return_dict, ensure_ascii=False)
if __name__ == '__main__':
app.run(debug=False, host='0.0.0.0', port=8888)
注意:若不设置跨域,前端将会报错:has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is
接口测试
接下来我们使用apifox进行接口测试,返回结果如下(接口测试成功!)