项目背景:
最近做的项目前端使用的Vue3 + Vite ,需要集成echarts ,一开始的使用方式是在main.js 里配置 直接挂载在
// 全局挂载echarts app.config.globalProperties.echarts = echarts
下,在页面里调用const { proxy } = getCurrentInstance(); proxy.echarts 这样,在本地开发环境下没事,但是通过Vite 打包后发布到Nginx 下就出现错误。
正确的方式:
在 App.vue 父页面里 通过 provide 引入 Echarts 对象,在子孙页面里通过inject 来获取:
<template>
<div class="app-container">
<el-row>
<el-col :span="24">
<div class="description">
<div class="title">Hi,欢迎使用{{title}}!</div>
<div class="desc">公会管理系统通过信息化、智能化的手段,使公会管理工作更加标准、规范,极大的提升了工会管理工作的质量和效率,加强了各级组织、组织与职工之间的上下联动,为企业稳步发展奠定坚实的基础。</div>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8" v-for="(item,index) in descArray">
<card-desc :desc="item.desc" :data="item.data" :unit="item.unit" :imgSrc="item.imgSrc" :bgColor="item.bgColor"></card-desc>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<ReceptionTrend></ReceptionTrend>
</el-col>
<el-col :span="8">
<SystemConstruction></SystemConstruction>
</el-col>
<el-col :span="8">
<DistributeMaterial></DistributeMaterial>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<ReceptionRank></ReceptionRank>
</el-col>
<el-col :span="8">
<DeviceStatusPie></DeviceStatusPie>
</el-col>
<el-col :span="8">
<DistributeMaterialsRank></DistributeMaterialsRank>
</el-col>
</el-row>
</div>
</template>
<script setup name="Index">
import CardDesc from '@/components/WayStation/CardDesc'
import ReceptionTrend from '@/components/WayStation/ReceptionTrend'
import SystemConstruction from '@/components/WayStation/SystemConstruction'
import DistributeMaterial from '@/components/WayStation/DistributeMaterial'
import ReceptionRank from '@/components/WayStation/ReceptionRank'
import DeviceStatusPie from '@/components/WayStation/DeviceStatusPie'
import DistributeMaterialsRank from '@/components/WayStation/DistributeMaterialsRank'
import c1 from '@/assets/waystation/index/home-icon-yizhan@1x.png'
import c2 from '@/assets/waystation/index/home-icon-renci@1x.png'
import c3 from '@/assets/waystation/index/home-icon-ywuzi@1x.png'
import settings from '@/settings'
import { getTotal } from '@/api/index/index'
import * as echarts from 'echarts'
provide('echart', echarts)
const { proxy } = getCurrentInstance();
const title = ref(settings.title)
const descArray = ref([])
onMounted(()=> {
descArray.value = [{desc:'驿站接入数量',data:'',unit:'个',imgSrc:c1,bgColor:'#FF9D01'},
{desc:'累计接待人数',data:'',unit:'人次',imgSrc:c2,bgColor:'#FF803F'},
{desc:'累计物资发放',data:'',unit:'件',imgSrc:c3,bgColor:'#4FC87F'}]
getTotal().then((result => {
const _data =result.data;
// console.log(_data)
_data.forEach((v,index)=>{
if (index == 0 && v.wsNumber){
descArray.value[0].data = v.wsNumber;
}else if (index == 1 && v.peopleTotal){
descArray.value[1].data = v.peopleTotal;
}else if (index == 2 && v.supplyNum){
descArray.value[2].data = v.supplyNum
}
})
}))
})
onUnmounted(()=>{
})
</script>
<style scoped lang="scss">
.el-row {
margin-bottom: 20px;
}
.el-col {
border-radius: 4px;
}
.description{
// background: #247FFF;
color: white;
height: 130px;
background-image: url("../assets/waystation/index/home-image-bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
border-radius: 4px;
.title {
font-size: 26px;
font-weight: 400;
color: #FFFFFF;
padding-top: 26px;
padding-left: 34px;
padding-right: 34px;
}
.desc {
font-size: 14px;
font-weight: 400;
color: #FFFFFF;
padding-left: 34px;
padding-top: 12px;
padding-right: 34px;
}
}
</style>
子孙页面:
<template>
<el-card class="box-card">
<div>
<div style="display: flex; align-items: center">
<img src="@/assets/waystation/index/home-image-lingxing.png" style="margin-right: 13px;width: 20px;height: 20px">
<span style="width: 150px; font-size: 18px; font-weight: 500;">接待人数趋势</span>
</div>
<div>
<img src="@/assets/waystation/index/home-image-line.png" style="width: 100%">
</div>
</div>
<div :style="{ 'width': width, 'height': height }" id="receptionTrend" class="myChart">
</div>
</el-card>
</template>
<script setup>
import { getSupplyPeopleTrend } from '@/api/index/index'
const { proxy } = getCurrentInstance();
const echart = inject('echart')
const title = "近七日驿站接待总人数趋势图"
const xAxisData = ref(['4月1日', '4月2日', '4月3日', '4月4日', '4月5日', '4月6日', '4月7日'])
const seriesData = ref([5, 20, 36, 10, 10, 20])
let myChart = null;
const props = defineProps({
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
})
function getData() {
xAxisData.value.length = 0;
seriesData.value.length = 0;
getSupplyPeopleTrend().then(result => {
// console.log(result.data)
result.data.map(v => {
xAxisData.value.push(v.time.slice(5))
seriesData.value.push(v.totalInCount)
})
renderEcharts(xAxisData, seriesData);
})
}
onMounted(() => {
initEcharts();
getData();
})
onUnmounted(() => {
if (!myChart.isDisposed) {
myChart.dispose();
}
})
function initEcharts() {
myChart = echart.init(document.getElementById("receptionTrend"));
}
function renderEcharts(xAxisData, seriesData) {
myChart.setOption({
title: {
text: title,
left: 'center',
top: '20',
textStyle: {
fontWeight: 400,
fontSize: 16,
color: 'rgba(0, 0, 0, 0.8)'
// fontStyle: 'normal'
}
},
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
// boundaryGap: false,
axisLine: {
show: true,
lineStyle: {
color: '#D1D1D1'
}
},
axisLabel: {
//x轴文字的配置
show: true,
interval: 0,//使x轴文字显示全
rotate: 40,
margin: 12,
textStyle: {
color: 'rgba(0, 0, 0, 0.6)'
}
},
// 刻度
axisTick: {
show: true,
alignWithLabel: true,
lineStyle: {
color: '#D1D1D1'
}
},
data: xAxisData.value
},
yAxis: {
name: '人数(人次)',
type: 'value',
axisLine: {
show: true,
lineStyle: {
color: '#D1D1D1'
}
},
axisLabel: {
show: true,
textStyle: {
color: 'rgba(0, 0, 0, 0.6)'
}
},
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.8)'
},
splitLine: {
lineStyle: {
// 使用深浅的间隔色
color: 'rgba(209, 209, 209, 0.35)',
with: '0.5'
}
}
},
grid: {
top: '25%',
left: '5%',
right: '5%',
bottom: '1%',
containLabel: true
},
series: [
{
name: '接待人数',
type: 'line',
symbol: 'circle',
symbolSize: 7,
// smooth: true,
data: seriesData.value,
lineStyle: {
color: "#409EFF"
},
itemStyle: {
color: "#409EFF"
},
areaStyle: {
color: new echart.graphic.LinearGradient(0, 1, 0, 0, [{
offset: 0.4,
color: "#fff"
}, {
offset: 1,
color: "rgba(64, 158, 255, 0.2)"
}]),
},
}
]
})
}
window.onresize = function () {
myChart.resize();
};
</script>
<style scoped lang="scss">
.myChart {
padding: 0 20px;
}
</style>
小结:
在 VUE3+Vite 里引入 Echarts 要通过provide / inject 方式引入,不要挂载到全局下。