问题描述
在vue下使用echarts搭建组件,控制台一直报错,相关代码如下:
<template>
<div :id="chartId" :style="{ height: height, width: width }"></div>
</template>
<script>
import {
defineComponent,
onMounted,
reactive,
toRefs,
watch,
ref,
nextTick,
} from "vue";
export default defineComponent({
props: {
chartId: {
type: String,
default() {
return "chart-id";
},
},
width: {
type: String,
default() {
return "1000px";
},
},
height: {
type: String,
default() {
return "600px";
},
},
title: {
type: String,
default() {
return "Echarts树状图";
},
},
data: {
type: Array,
default() {
return [];
},
},
columns: {
type: Array,
default() {
return [];
},
},
x: {
type: String,
default() {
return "";
},
},
y: {
type: Array,
default() {
return [];
},
},
loading: {
type: Boolean,
default() {
return false;
},
},
stack: {
type: Boolean,
default() {
return false;
},
},
clear: {
// 刷新时是否清除
type: Boolean,
default() {
return false;
},
},
},
setup(props, ctx) {
const myChart = ref(null);
function myChartInit() {
if (!myChart.value) {
myChart.value = echarts.init(document.getElementById(props.chartId));
}
}
function myChartClear() {
if (myChart.value && props.clear) {
myChart.value.clear();
}
}
function generateOptions() {
const options = {
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
legend: {
data: props.y,
},
tooltip: {},
dataset: {
dimension: props.columns,
source: props.data,
},
color: [
"#A4DBCC",
"#F56C6C",
"#DBC999",
"#DB9784",
"#D093DB",
"#91795D",
"#FFE2BF",
"#DEC3A4",
"#38778F",
"#A4CEDE",
],
};
const series = [];
for (let item of props.y) {
const serie = {
type: "bar",
name: item,
emphasis: {
focus: "series",
},
encode: {
x: props.x,
y: item,
},
};
if (props.stack) {
serie.stack = "total";
}
series.push(serie);
}
options.series = series;
return options;
}
function myChartSet() {
if (myChart.value) {
const options = generateOptions();
myChart.value.setOption(options);
}
}
onMounted(() => {
myChartInit();
myChartSet();
});
return { showLoading, hideLoading };
},
});
</script>
<style scoped>
</style>
只要使用到图表中的交互功能,控制台就报错
image问题解决
该问题的解决也是查阅了很久,使用百度搜索未找到任何解决办法,最后上了echarts的github主页,在其issues下查询到了相关问题,发现只要将代码中的ref改为shallowRef就能解决问题,目前官方还没有什么解释,不过猜测是因为ref将对象包装成响应式,这破坏了echarts对象中原本的一些api,所以改为shallowRef,就不会破坏其内部的api,代码修改为如下代码:
<template>
<div :id="chartId" :style="{ height: height, width: width }"></div>
</template>
<script>
import {
defineComponent,
onMounted,
ref,
reactive,
toRefs,
watch,
shallowRef,
nextTick,
} from "vue";
export default defineComponent({
props: {
chartId: {
type: String,
default() {
return "chart-id";
},
},
width: {
type: String,
default() {
return "1000px";
},
},
height: {
type: String,
default() {
return "600px";
},
},
title: {
type: String,
default() {
return "Echarts树状图";
},
},
data: {
type: Array,
default() {
return [];
},
},
columns: {
type: Array,
default() {
return [];
},
},
x: {
type: String,
default() {
return "";
},
},
y: {
type: Array,
default() {
return [];
},
},
loading: {
type: Boolean,
default() {
return false;
},
},
stack: {
type: Boolean,
default() {
return false;
},
},
clear: {
// 刷新时是否清除
type: Boolean,
default() {
return false;
},
},
},
setup(props, ctx) {
// 只有使用shallowRef才不会报错
const myChart = shallowRef(null);
function myChartInit() {
if (!myChart.value) {
myChart.value = echarts.init(document.getElementById(props.chartId));
}
}
function myChartClear() {
if (myChart.value && props.clear) {
myChart.value.clear();
}
}
function generateOptions() {
const options = {
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
legend: {
data: props.y,
},
tooltip: {},
dataset: {
dimension: props.columns,
source: props.data,
},
color: [
"#A4DBCC",
"#F56C6C",
"#DBC999",
],
};
const series = [];
for (let item of props.y) {
const serie = {
type: "bar",
name: item,
emphasis: {
focus: "series",
},
encode: {
x: props.x,
y: item,
},
};
if (props.stack) {
serie.stack = "total";
}
series.push(serie);
}
options.series = series;
return options;
}
function myChartSet() {
if (myChart.value) {
const options = generateOptions();
myChart.value.setOption(options);
}
}
function showLoading() {
// 显示加载中
myChart.value.showLoading();
}
function hideLoading() {
// 关闭加载中
myChart.value.hideLoading();
}
watch(
() => props.loading,
() => {
if (props.loading) {
showLoading();
} else {
hideLoading();
}
}
);
watch(
() => [props.data, props.columns, props.x, props.y],
() => {
myChartClear();
myChartSet();
},
{
deep: true,
}
);
onMounted(() => {
myChartInit();
myChartSet();
});
return { showLoading, hideLoading };
},
});
</script>
<style scoped>
</style>
网友评论