Vue3+Vite 引用Echarts 正确方式

项目背景:

最近做的项目前端使用的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 方式引入,不要挂载到全局下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 + TypeScript + Vite项目中使用echarts来请求并展示两个图表的数据,你可以按照以下步骤进行操作: 1. 在项目中安装echarts依赖。可以使用npm或yarn命令来安装echarts,例如:`npm install echarts --save`。 2. 在main.ts文件中引入echarts,并将其挂载到Vue实例上。你可以按照以下代码示例来实现: ```typescript import { createApp } from "vue"; import App from "./App.vue"; import echarts from "echarts"; const app = createApp(App); app.config.globalProperties.$echarts = echarts; ``` 通过以上代码,你已经将echarts挂载到了Vue实例的全局属性$echarts上。 3. 在需要使用echarts的组件中引入echarts,并在页面渲染完成后使用echarts来请求并展示图表数据。假设你要在App.vue组件中展示两个图表的数据,你可以按照以下代码示例来实现: ```vue <template> <div> <div ref="chart1" style="width: 400px; height: 300px;"></div> <div ref="chart2" style="width: 400px; height: 300px;"></div> </div> </template> <script> import { ref, onMounted } from "vue"; export default { name: "App", setup() { const chart1 = ref(null); const chart2 = ref(null); onMounted(() => { // 请求图表1的数据并绘制图表 const chart1Data = fetchDataForChart1(); // 根据实际情况获取图表1的数据 const chart1Instance = $echarts.init(chart1.value); chart1Instance.setOption(chart1Data); // 请求图表2的数据并绘制图表 const chart2Data = fetchDataForChart2(); // 根据实际情况获取图表2的数据 const chart2Instance = $echarts.init(chart2.value); chart2Instance.setOption(chart2Data); }); return { chart1, chart2, }; }, }; function fetchDataForChart1() { // 根据实际情况请求图表1的数据并返回 // 例如:return axios.get("/api/chart1").then((res) => res.data); } function fetchDataForChart2() { // 根据实际情况请求图表2的数据并返回 // 例如:return axios.get("/api/chart2").then((res) => res.data); } </script> ``` 在以上代码中,我们使用了`ref`和`onMounted`来获取图表的DOM元素,并在页面渲染完成后使用echarts来请求并展示图表数据。 请注意,以上代码仅为示例代码,你需要根据实际情况来实现`fetchDataForChart1`和`fetchDataForChart2`方法来请求图表数据。此外,你还需要根据实际需求来配置echarts的图表选项。 #### 引用[.reference_title] - *1* *2* [vue3+ts+vite 使用echarts](https://blog.csdn.net/gusensen/article/details/129445665)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [vue3+vite+ts+echarts项目问题汇总](https://blog.csdn.net/weixin_41107170/article/details/126401617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值