前期回顾
目录
vue2封装
子组件
<template>
<div :id="uuid" :style="style"></div>
</template>
<script>
import * as echarts from "echarts";
const idGen = () => {
return new Date().getTime();
};
export default {
props: {
height: {
type: String,
default: "400px",
},
width: {
type: String,
default: "600px",
},
options: {
type: Object,
default: null,
},
},
data() {
return {
uuid: null,
myChart: null,
};
},
watch: {
width(a, b) {
if (this.myChart) {
// 这里需要异步才能生效
setTimeout(() => {
this.myChart.resize({
animation: {
duration: 500,
},
});
}, 0);
}
},
options() {
if (this.myChart) {
// notMerge 可选。是否不跟之前设置的 option 进行合并。默认为 false。即表示合并。
//合并的规则,详见 组件合并模式。如果为 true,表示所有组件都会被删除,然后根据新 option 创建所有新组件
this.myChart.setOption(this.options, {
notMerge: true,
});
}
},
},
computed: {
style() {
return {
height: this.height,
width: this.width,
};
},
},
created() {
this.uuid = idGen();
},
mounted() {
// 准备实例
this.myChart = echarts.init(document.getElementById(this.uuid));
// 应用配置项
this.myChart.setOption(this.options);
},
};
</script>
页面使用
<template>
<div id="app">
<MyEcharts :options="options" :width="width"></MyEcharts>
<button @click="changeWidth">changeWidth</button>
<button @click="changeOpt">changeOpt</button>
</div>
</template>
<script>
import MyEcharts from "./components/MyEcharts.vue";
import { options1, options2 } from "./options";
export default {
name: "App",
components: {
MyEcharts,
},
data() {
return {
options: options1,
width: "600px",
};
},
methods: {
changeWidth() {
if (this.width == "600px") {
console.log(1);
this.width = "800px";
} else {
console.log(2);
this.width = "600px";
}
},
changeOpt() {
if (this.options == options1) {
this.options = options2;
} else {
this.options = options1;
}
},
},
};
</script>
vue3封装
子组件
<template>
<div :id="uid" :style="style"></div>
</template>
<script setup>
import { defineProps, defineEmits, onMounted, reactive, ref } from "vue";
const emits = defineEmits([]);
import * as echarts from "echarts";
// 因为是封装的组件,会多次调用,id不能重复,要在初始化之前写,不然会报错dom为定义
let uid = ref(null);
onBeforeMount(() => {
uid.value = `echarts-uid-${parseInt(Math.random() * 1000000)}`;
// 也可以用毫秒数作为id
// uid.value = `echarts-uid-${new Date().getTime()}`;
});
onMounted(() => {
var myChart = echarts.init(document.getElementById(uid.value));
// 在template中可以直接取props中的值,但是在script中不行,因为script是在挂载之前执行的
myChart.setOption(props.myOption, {
notMerge: true, //不和之前的option合并
});
// 监听页面的大小
window.addEventListener("resize", () => {
myChart.resize({
animation: {
duration: 300,
},
});
});
});
const props = defineProps({
style: {
type: Object,
default: () => ({
width: "600px",
height: "400px",
}),
},
myOption: {
type: Object,
default: () => ({}),
},
});
</script>
<style lang="scss" scoped></style>
页面使用
<template>
<div class="heder">
<my-chart :my-option="chartData"></my-chart>
<my-chart :my-option="chartData2"></my-chart>
</div>
<div class="heder">
<my-chart :my-option="chartData3"></my-chart>
<my-chart :my-option="chartData4"></my-chart>
</div>
</template>
<script setup>
import myChart from "comp/myEcharts/index.vue";
import {
defineProps,
defineEmits,
onMounted,
reactive,
ref,
toRefs,
} from "vue";
let category = [];
let dottedBase = +new Date();
let lineData = [];
let barData = [];
for (let i = 0; i < 20; i++) {
let date = new Date((dottedBase += 3600 * 24 * 1000));
category.push(
[date.getFullYear(), date.getMonth() + 1, date.getDate()].join("-")
);
let b = Math.random() * 200;
let d = Math.random() * 200;
barData.push(b);
lineData.push(d + b);
}
let state = reactive({
chartData: {
tooltip: {
trigger: "item",
},
legend: {
top: "5%",
left: "center",
},
series: [
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
label: {
show: false,
position: "center",
},
emphasis: {
label: {
show: true,
fontSize: "40",
fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: "Search Engine" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union Ads" },
{ value: 300, name: "Video Ads" },
],
},
],
},
chartData2: {
title: [
{
text: "Radial Polar Bar Label Position (middle)",
},
],
polar: {
radius: [30, "80%"],
},
radiusAxis: {
max: 4,
},
angleAxis: {
type: "category",
data: ["a", "b", "c", "d"],
startAngle: 75,
},
tooltip: {},
series: {
type: "bar",
data: [2, 1.2, 2.4, 3.6],
coordinateSystem: "polar",
label: {
show: true,
position: "middle",
formatter: "{b}: {c}",
},
},
animation: false,
},
chartData3: {
// option
backgroundColor: "#0f375f",
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
legend: {
data: ["line", "bar"],
textStyle: {
color: "#ccc",
},
},
xAxis: {
data: category,
axisLine: {
lineStyle: {
color: "#ccc",
},
},
},
yAxis: {
splitLine: { show: false },
axisLine: {
lineStyle: {
color: "#ccc",
},
},
},
series: [
{
name: "line",
type: "line",
smooth: true,
showAllSymbol: true,
symbol: "emptyCircle",
symbolSize: 15,
data: lineData,
},
{
name: "bar",
type: "bar",
barWidth: 10,
itemStyle: {
borderRadius: 5,
},
data: barData,
},
{
name: "line",
type: "bar",
barGap: "-100%",
barWidth: 10,
z: -12,
data: lineData,
},
{
name: "dotted",
type: "pictorialBar",
symbol: "rect",
itemStyle: {
color: "#0f375f",
},
symbolRepeat: true,
symbolSize: [12, 4],
symbolMargin: 1,
z: -10,
data: lineData,
},
],
},
chartData4: {
title: [
{
text: "Radial Polar Bar Label Position (middle)",
},
],
polar: {
radius: [30, "80%"],
},
radiusAxis: {
max: 4,
},
angleAxis: {
type: "category",
data: ["a", "b", "c", "d"],
startAngle: 75,
},
tooltip: {},
series: {
type: "bar",
data: [2, 1.2, 2.4, 3.6],
coordinateSystem: "polar",
label: {
show: true,
position: "middle",
formatter: "{b}: {c}",
},
},
animation: false,
},
});
const { chartData, chartData2, chartData3, chartData4 } = toRefs(state);
</script>
<style lang="scss" scoped>
.heder {
display: flex;
}
</style>
总结:
封装代码不多,只要是echarts的数据多!真实项目按照公司结构在优化,