1.技术选型
- 3.0目前不稳定,且使用element ui 组件库
- 使用vue 2.6版本
vue add element
- vue 集成了element,使用按需加载
1.2 vue-charts图表组件介绍
推荐图表在简单场景中的使用
1.3 v-charts图表组件介绍
在使用echarts生成图表的时候,经常需要使用做繁琐的数据类型转化,修改复杂的配置项,v-charts的出现正是为了解决这个痛点。
- 文档
https://v-charts.js.org/#/
基于vue2.0 和echarts封装的v-charts图表组件,只需要同意提供一种对前后端都友好的数据格式设置简单的配置项,便轻松生成常见的图表。
- 按需加载
// vcharts.js
import Vue from "vue";
import VeLine from "v-charts/lib/line.common";
// 全局注册组件
Vue.component("ve-line", VeLine);
- 在页面中使用
<template>
<ve-line :data="chartData"></ve-line>
</template>
<script>
export default {
name: "SaleView",
props: {
msg: String
},
data() {
return {
chartData: {
columns: ["date", "PV"],
rows: [
{ date: "01-01", PV: 1231 },
{ date: "01-02", PV: 1223 },
{ date: "01-03", PV: 2123 },
{ date: "01-04", PV: 4123 },
{ date: "01-05", PV: 3123 },
{ date: "01-06", PV: 7123 }
]
}
};
}
};
- 生成效果图

image.png
使用vchartsde 问题,有很多属性都是自定义的话,需要重新学习,并且修改复杂的样式,还是需要修改echarts的属性
- 一般使用在简单图表且样式比较简单那的图表使用场景
3.自定义图表效果实现
1,定义基础组件
// commonCard.vue
<template>
<div class="common-card">
<div class="title">{{ title }}</div>
<div class="value">{{ value }}</div>
<div class="chart">
<slot></slot>
</div>
<div class="line"></div>
<div class="total">
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ""
},
value: {
type: String,
default: ""
}
}
};
</script>
<style lang="scss" scoped>
.title {
font-size: 12px;
color: #999;
}
.value {
font-size: 24px;
color: #333;
margin-top: 5px;
letter-spacing: 1px;
}
.chart {
height: 50px;
}
.line {
margin: 10px 0;
border-top: 1px solid #eee;
}
.total {
font-size: 12px;
color: #666;
}
</style>
<style lang="scss">
.emphasis {
color: #000;
font-weight: 700;
margin-left: 5px;
}
.increase {
width: 0;
height: 0;
border: 3px;
border-color: transparent transparent red transparent;
border-style: solid;
margin: 0 0 3px 5px;
}
.decrease {
width: 0;
height: 0;
border: 3px;
border-color: green transparent transparent transparent;
border-style: solid;
margin: 3px 0 0px 5px;
}
</style>
2.使用mixins混入
- 注意:引用图表,这里不能用动态加载,否则刷新会包dom找不到
// 导出公共的组件 commonCardMixins.js
import CommonCard from "../components/commonCard";
export default {
components: {
CommonCard
}
};
3.生成自定义图表
<template>
<common-card title="累计用户数" value="1,087,503">
<template>
<div
id="total-user-chart"
:style="{ width: '100%', height: '100%' }"
></div>
</template>
<template v-slot:footer>
<div class="tatal-users-footer">
<span>日同比 </span>
<span class="emphasis">8.73%</span>
<span class="increase"></span>
<span class="month">月同比 </span>
<span class="emphasis">35.91%</span>
<span class="decrease"></span>
</div>
</template>
</common-card>
</template>
<script>
import commonCardMixin from "../../mixins/commonCardMixin";
export default {
mixins: [commonCardMixin],
mounted() {
this.initChart();
},
methods: {
initChart() {
const chartDom = document.getElementById("total-user-chart");
const chart = this.$echarts.init(chartDom);
let option = {
tooltip: {
trigger: "axis"
},
xAxis: {
type: "value",
boundaryGap: false,
show: false // 不展示x轴
},
yAxis: {
type: "category",
show: false // 不展示y轴
},
grid: {
top: 0,
bottom: 0,
left: 0,
right: 0
},
series: [
// 两条线合并
{
data: [120],
type: "bar",
barWidth: 12,
stack: "总量", // 相同数据进行合并,图表重叠
smooth: true,
itemStyle: {
color: "#45c946"
}
},
{
data: [200],
type: "bar",
stack: "总量",
itemStyle: {
color: "#eee"
}
},
{
type: "custom", // 自定义类型
data: [120],
stack: "总量",
renderItem: (params, api) => {
const value = api.value(0);
// 取出点的坐标系
const endPoint = api.coord([value, 0]);
return {
type: "group", // 设置类型为组
children: [
{
type: "path", // 类型为svg
position: endPoint,
shape: {
d:
"M234.88884163 377.47806845l279.65492248 279.65492248 278.8075161-278.8075161z",
x: -5, // 坐标
y: -20,
width: 10, // 大小
height: 10,
layout: "cover" // 根据尺寸填充
},
style: {
fill: "#45c946" // 填充颜色
}
},
{
type: "path",
position: endPoint,
shape: {
d:
"M870.73079499 686.14387737l-362.02410036-362.02410034-360.92762642 360.92762644Z",
x: -5,
y: 10,
width: 10,
height: 10,
layout: "cover" // 填充
},
style: {
fill: "#45c946"
}
}
]
};
}
}
]
};
chart.setOption(option);
}
}
};
</script>
<style lang="scss" scoped>
.tatal-users-footer {
display: flex;
align-items: center;
.month {
margin-left: 10px;
}
}
</style>
4.效果如下
`
image (1).png
5.provide-inject
机制:父组件通过provide函数将数据向所有子组件传入
// index主页面
provide () {
// 传值
return {
// 父组件向下传递给子组件
wordCloudFun: this.wordCloud, // 传递数据
LiquidFun: this.liquidData
};
},
- 看源码,vue init inject赋值 是在beforecreate 和create 之间
- 但实际上,我们获取词云图数据是在mounted 的时候,所以,我们要将provide传值以函数的形式
// index主页面
data(){
return {
wordCloud:[], // 云数据
liquidData:[] // 水球图数据
}
},
methods: {
getWorudeFun () {
return this.wordCloud
},
getLiquidFun () {
return this.liquidData
}
},
provide () {
// 传值
return {
// 父组件向下传递给子组件
wordCloudFun: this.getWorudeFun, // 传递函数
LiquidFun: this.getLiquidFun
};
},
- 子组件
// wordCloud.vue
inject: ["wordCloudFun"], // 子组件接受父组件的词云数据
computed: {
wordCloudData() {
return this.wordCloudFun();
},
data: this.wordCloudData, // 赋值
- 优化写法
- mixins :对于模块直接数据无关联的数据,只注重页面渲染,不关心业务逻辑
// commonDataMixin.js
export default {
inject: ["wordCloudFun", "LiquidFun"],
computed: {
wordCloudData() {
return this.wordCloudFun();
},
liquiData() {
return this.LiquidFun();
},
},
};
- 页面引用
// wordCloud.vue
import commonDataMixins from '../../mixins/commonDataMixins'
mixins: [commonDataMixins],
- 公共处理函数数据
// 千分位 67,890,197
function format(v) {
// ?先表示后面的表达式是正确的 ,后面表示3位数字 $直接到结尾都是这个逻辑
const reg = /\d{1,3}(?=(\d{3})+$)/g;
// 加逗号$&:获取到匹配的值,后面加任何想加的,比如,$&,:就是拿值加逗号
return `${v}`.replace(reg, "$&,");
}
- 项目启动 core.js 报错原因
- core.js is not found
原因是用的最新的core.js,版本不一样,需要安装对应的旧版本,安装3.0之前的最新版本,就能解决问题
``