项目背景:

最近做的项目前端使用的Vue3 + Vite ,需要集成echarts ,一开始的使用方式是在main.js 里配置 直接挂载在

// 全局挂载echarts app.config.globalProperties.echarts = echarts

下,在页面里调用const { proxy } = getCurrentInstance(); proxy.echarts 这样,在本地开发环境下没事,但是通过Vite 打包后发布到Nginx 下就出现错误。

正确的方式:

在index.vue 父页面里 通过provide 引入 Echarts 对象,在子孙页面里通过inject 来获取:

index.vue

<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 方式引入,不要挂载到全局下。

Logo

前往低代码交流专区

更多推荐