最清晰、最实用、企业级标准写法: Vue2 + ECharts 和 Vue3 + ECharts 两套完整代码,直接复制就能跑,包含:
- 封装通用图表组件
- 深色主题
- 自适应窗口
- 实时刷新
- 多图表(折线、柱状、饼图)
一、Vue2 + ECharts 完整版
1. 安装
npm install echarts@4.9.0 --save
2. 全局引入(main.js)
import Vue from 'vue'
import App from './App.vue'
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
new Vue({
render: h => h(App)
}).$mount('#app')
3. 封装 ECharts 通用组件(components/ChartBox.vue)
<template>
<div :id="id" :style="style"></div>
</template>
<script>
export default {
name: 'ChartBox',
props: {
id: { type: String, required: true },
width: { type: String, default: '100%' },
height: { type: String, default: '300px' },
option: { type: Object, required: true }
},
data() {
return {
chart: null
}
},
computed: {
style() {
return { width: this.width, height: this.height }
}
},
watch: {
option: {
handler() {
this.setOption()
},
deep: true
}
},
mounted() {
this.initChart()
window.addEventListener('resize', this.resize)
},
beforeDestroy() {
window.removeEventListener('resize', this.resize)
this.chart?.dispose()
},
methods: {
initChart() {
this.chart = this.$echarts.init(document.getElementById(this.id), 'dark')
this.setOption()
},
setOption() {
this.chart?.setOption(this.option)
},
resize() {
this.chart?.resize()
}
}
}
</script>
4. 页面使用(实时刷新+多图表)
<template>
<div class="wrap">
<ChartBox id="bar" height="300px" :option="barOption" />
<ChartBox id="line" height="300px" :option="lineOption" />
<ChartBox id="pie" height="300px" :option="pieOption" />
</div>
</template>
<script>
import ChartBox from '@/components/ChartBox'
export default {
components: { ChartBox },
data() {
return {
barOption: {},
lineOption: {},
pieOption: {}
}
},
mounted() {
this.renderCharts()
this.timer = setInterval(() => this.renderCharts(), 3000)
},
beforeDestroy() {
clearInterval(this.timer)
},
methods: {
randData() {
return [120, 200, 150, 80, 70].map(v => v + Math.random() * 50)
},
renderCharts() {
this.barOption = {
title: { text: '柱状图' },
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
series: [{ type: 'bar', data: this.randData() }]
}
this.lineOption = {
title: { text: '折线图' },
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
series: [{ type: 'line', data: this.randData() }]
}
this.pieOption = {
title: { text: '饼图' },
series: [{
type: 'pie',
radius: ['30%', '60%'],
data: [
{ value: 300, name: 'A' },
{ value: 200, name: 'B' },
{ value: 150, name: 'C' }
]
}]
}
}
}
}
</script>
<style scoped>
.wrap {
background: #081022;
padding: 20px;
}
</style>
二、Vue3 + ECharts 完整版(Composition API)
1. 安装
npm install echarts --save
2. 封装通用组件(components/ChartBox.vue)
<template>
<div :id="id" :style="style"></div>
</template>
<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
id: { type: String, required: true },
width: { type: String, default: '100%' },
height: { type: String, default: '300px' },
option: { type: Object, required: true }
})
const chart = ref(null)
const style = computed(() => ({ width: props.width, height: props.height }))
const initChart = () => {
chart.value = echarts.init(document.getElementById(props.id), 'dark')
chart.value.setOption(props.option)
}
const resize = () => chart.value?.resize()
watch(() => props.option, (val) => {
chart.value?.setOption(val)
}, { deep: true })
onMounted(() => {
initChart()
window.addEventListener('resize', resize)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', resize)
chart.value?.dispose()
})
</script>
3. 页面使用(多图表+实时刷新)
<template>
<div class="wrap">
<ChartBox id="bar" height="280px" :option="barOption" />
<ChartBox id="line" height="280px" :option="lineOption" />
<ChartBox id="pie" height="280px" :option="pieOption" />
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import ChartBox from '@/components/ChartBox'
const barOption = ref({})
const lineOption = ref({})
const pieOption = ref({})
let timer = null
const randData = () => [120, 200, 150, 80, 70].map(v => v + Math.random() * 50)
const render = () => {
barOption.value = {
title: { text: 'Vue3 柱状图' },
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
series: [{ type: 'bar', data: randData() }]
}
lineOption.value = {
title: { text: 'Vue3 折线图' },
xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
yAxis: {},
series: [{ type: 'line', smooth: true, data: randData() }]
}
pieOption.value = {
title: { text: 'Vue3 饼图' },
series: [{
type: 'pie', radius: ['30%', '60%'],
data: [
{ value: 335, name: 'A' },
{ value: 310, name: 'B' },
{ value: 234, name: 'C' }
]
}]
}
}
onMounted(() => {
render()
timer = setInterval(render, 3000)
})
onBeforeUnmount(() => clearInterval(timer))
</script>
<style scoped>
.wrap {
background: #081022;
padding: 20px;
}
</style>
三、核心亮点(企业标准)
- 封装通用组件,一次封装,全项目复用
- 深色主题:
init(..., 'dark') - 响应式自适应
- watch 监听数据自动更新
- 定时器实时刷新
- 销毁自动清理,防止内存泄漏
- 支持所有图表:折线、柱状、饼图、地图、仪表盘