Vue3 父组件数据改变Echarts子组件图表没有变化
使用vue3写页面,引入一个echarts图,父组件数据改变,图表没有重新渲染。1、echarts图组件监听数据(数据改变,重新渲染)注意:父组件正常调接口 传值即可。
·
一、问题
使用vue3写页面,引入一个echarts图,父组件数据改变,图表没有重新渲染。
二、目标效果图

三、解决(数据变了, 图表不变化)
只需要2步:
1、echarts图组件监听数据(数据改变,重新渲染)
watch(
() => props.chartData,
() => {
//dispose为了解决警告 There is a chart instance already initialized on the dom.
echart.dispose(document.getElementById('LineBar'))
initChart() //重新渲染的方法
},{deep: true}
)
2、在使用setOption()方法之前,重新给option中的数据赋值即可,代码如下:
let initChart = () => {
let Echarts = echarts.init(document.getElementById('LineBar'))
//重新赋值(必须,否则渲染不上)
option.value.xAxis.data = props.chartData.xAxisData
option.value.series[0].data = props.chartData.data
// 绘制图表
Echarts.setOption(option.value)
// 自适应大小
window.addEventListener(
'resize',
(window.onresize = () => {
Echarts.resize()
})
)
}
注意:父组件正常调接口 传值即可
解决警告 There is a chart instance already initialized on the dom.
echart.dispose(document.getElementById('LineBar'))
解决警告Instance ec_1680155339347 has been disposed
不要使用以下写法:(暂时不清楚具体原因)
window.addEventListener(
'resize',
(window.onresize = () => {
Echarts.resize()
})
)
改为这样写法:
window.addEventListener('resize', onResize(Echarts))
let onResize = (Echarts) => {
window.onresize = () => {
Echarts.resize()
}
}
四、Echarts子组件 完整代码
<template>
<div id="LineBar"></div>
</template>
<script name="LineBar" setup>
import { onMounted, defineProps, watch } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
chartData: {
type: Object,
required: true
}
})
watch(
() => props.chartData,
() => {
//解决警告 There is a chart instance already initialized on the dom.
echart.dispose(document.getElementById('LineBar'))
initChart()
},
{deep: true}
)
let option = ref({
tooltip: {
trigger: 'axis'
},
// legend: {
// data: vulnerabilityTrendData.value.xdata
// },
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: props.chartData.xAxisData
},
yAxis: {
type: 'value'
},
series: [
{
name: 'ddd',
type: 'line',
smooth: true,
data: props.chartData.data,
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(46, 121, 255, 0.2)' // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(46, 121, 255, 0.0001)' // 100% 处的颜色
}
]
}
},
color: '#2E79FF',
lineStyle: {
color: {
colorStops: [
{
offset: 0,
color: '#8477FF'
},
{
offset: 1,
color: '#5CCAFF'
}
]
},
width: 2,
shadowOffsetY: 12,
shadowColor: 'rgba(59, 138, 254, 0.1)'
}
}
]
})
let echart = echarts
onMounted(() => {
initChart()
})
let initChart = () => {
let Echarts = echarts.init(document.getElementById('LineBar'))
//手动赋值
option.value.xAxis.data = props.chartData.xAxisData
option.value.series[0].data = props.chartData.data
// 绘制图表
Echarts.setOption(option.value)
// 自适应大小(这样写会出现:父组件数据修改,浏览器窗口大小改变,会警告Instance ec_1680155339347 has been disposed)
//window.addEventListener(
// 'resize',
// (window.onresize = () => {
// Echarts.resize()
// })
//)
//改成以下写法
window.addEventListener('resize', onResize(Echarts))
}
let onResize = (Echarts) => {
window.onresize = () => {
Echarts.resize()
}
}
</script>
<style scoped></style>
解决方法二
options不设置为变量,设置为函数
const options = () => {
const { xData, yData } = { ...props.chartData };
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
color: ['#4874CB', '#ED812F'],
legend: {
y: 'bottom',
},
title: {
text: '成本使用情况',
left: 'center',
},
grid: {
left: '3%',
right: '4%',
bottom: '10%',
containLabel: true,
},
xAxis: {
type: 'value',
},
yAxis: {
type: 'category',
data: xData,
},
series: [
{
name: '花费成本',
type: 'bar',
stack: 'total',
label: {
show: true,
},
emphasis: {
focus: 'series',
},
data: yData[0],
},
{
name: '剩余成本',
type: 'bar',
stack: 'total',
label: {
show: true,
},
emphasis: {
focus: 'series',
},
data: yData[1],
},
],
};
};
使用时
function onInit() {
if (isEmpty(chartDom.value)) {
chartDom.value = proxy.$echarts.init(proxy.$refs[CHART_REF]);
}
chartDom.value.setOption(options(), true); // 第二个参数为true,可以防止有残留的连线
}
onMounted(() => onInit());
// watch(() => props.chartFlag, () => { //设置这个参数,在父组件数据变化时,设置chartFlag=!chartFlag
// onInit();
//});
// 否则需要设置深度
watch(() => props.chartData, () => {
onInit();
}, {
deep: true,
});
更多推荐



所有评论(0)