利用vue watch深度监听实现实时更新,还可以使用v-if控制Boolean值重新渲染,但是体验很差,所以还是推荐使用watch实现重新渲染。
父组件:
<echarts-interval :topTen="this.topTen"></echarts-interval>
父组件传过来的值:
props: {
topTen: {
type: Object
}
},
子组件声明变量:
saleIntervalChart: null
初始化图表:
mounted() {
this.drawLine();
},
drawLine() {
// 基于准备好的dom,初始化echarts实例
this.saleIntervalChart = this.$echarts.init(document.getElementById('saleIntervalChart'));
// 绘制图表
this.draw();
//自适应浏览器放大缩小
window.onresize = function () {
this.saleIntervalChart.resize();
}
}
在echarts中,setOption是渲染图表的操作,所以我们将这个操作封装起来。
draw() {
this.saleIntervalChart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: {
show: true, readOnly: false,
optionToContent: function (opt) {
let axisData = opt.xAxis[0].data; //坐标数据
let series = opt.series; //折线图数据
let tdHeads = '<td style="padding: 0 10px"></td>'; //表头
let tdBodys = ''; //数据
series.forEach(function (item) {
//组装表头
tdHeads += '<td style="padding: 0 10px">' + item.name + '</td>';
});
let table = '<table border="1" style="margin-left:20px;border-collapse:collapse;font-size:14px;text-align:center"><tbody><tr>' + tdHeads + ' </tr>';
for (let i = 0, l = axisData.length; i < l; i++) {
for (let j = 0; j < series.length; j++) {
//组装表数据
tdBodys += '<td>' + series[j].data[i] + '</td>';
}
table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
tdBodys = '';
}
table += '</tbody></table>';
return table;
}
},
magicType: {show: true, type: ['bar', 'line']},
myTool: {
title: '还原',
show: true,
onclick: () => {
this.saleIntervalChart.setOption({
xAxis: [
{
type: 'category',
data: this.topTen.goodsNameList,
boundaryGap: true,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '销售金额/销售单数',
axisLabel: {
formatter: '{value}'
}
},
{
type: 'value',
name: '平均售价',
axisLabel: {
formatter: '{value}'
}
}
],
series: [
{
name: '销售金额',
type: 'bar',
barMaxWidth: 30,
data: this.topTen.totalSaleAmount,
yAxisIndex: 0
},
{
name: '销售单数',
type: 'bar',
barMaxWidth: 30,
data: this.topTen.totalSaleCount,
yAxisIndex: 0
},
{
name: '平均售价',
type: 'line',
barMaxWidth: 30,
data: this.topTen.averageSalePrice,
yAxisIndex: 1
}
]
})
},
icon: "path://M197.7088 478.72l39.68-39.168a19.2 19.2 0 1 1 26.9824 27.2896l-73.344 72.448a19.2 19.2 0 0 1-26.9824 0l-75.136-74.24A19.2 19.2 0 1 1 115.8912 437.76l43.0592 42.5472C175.616 300.6464 326.7328 160 510.72 160c195.1232 0 353.28 158.1568 353.28 353.28 0 195.1232-158.1568 353.28-353.28 353.28a352.0512 352.0512 0 0 1-242.0224-95.9232 19.2 19.2 0 1 1 26.2912-27.9808 313.6768 313.6768 0 0 0 215.7312 85.504c173.9008 0 314.88-140.9792 314.88-314.88 0-173.9008-140.9792-314.88-314.88-314.88-162.2272 0-295.808 122.6752-313.0112 280.32z",
},
saveAsImage: {show: true, name: '销售数量TOP10'}
}
},
grid: {
bottom: '6%'
},
legend: {
data: ['销售金额', '销售单数', '平均售价']
},
xAxis: [
{
type: 'category',
data: this.topTen.goodsNameList,
boundaryGap: true,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '销售金额/销售单数',
axisLabel: {
formatter: '{value}'
}
},
{
type: 'value',
name: '平均售价',
axisLabel: {
formatter: '{value}'
}
}
],
series: [
{
name: '销售金额',
type: 'bar',
barMaxWidth: 30,
data: this.topTen.totalSaleAmount,
yAxisIndex: 0
},
{
name: '销售单数',
type: 'bar',
barMaxWidth: 30,
data: this.topTen.totalSaleCount,
yAxisIndex: 0
},
{
name: '平均售价',
type: 'line',
barMaxWidth: 30,
data: this.topTen.averageSalePrice,
yAxisIndex: 1
}
]
});
}
watch深度监听,当父组件数据改变就执行this.draw重新绘制图表。
watch: {
topTen: {
deep: true,
handler: function () {
this.draw()
}
}
}