vue3集成echarts最佳实践

安装 echarts

npm install echarts --save

两种引用方式

非虚拟 dom
import * as echarts from 'echarts';

var chartDom = document.getElementById('mychart');
var myChart = echarts.init(chartDom);
var option;

option = {
  title: {
    text: 'Referer of a Website',
    subtext: 'Fake Data',
    left: 'center'
  },
  tooltip: {
    trigger: 'item'
  },
  legend: {
    orient: 'vertical',
    left: 'left'
  },
  series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: '50%',
      data: [
        { value: 1048, name: 'Search Engine' },
        { value: 735, name: 'Direct' },
        { value: 580, name: 'Email' },
        { value: 484, name: 'Union Ads' },
        { value: 300, name: 'Video Ads' }
      ],
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
};

option && myChart.setOption(option);

------ tsx 或者 template

   <div
                ref='pieChartRef'
                id={'myChart'}
                style={{
                    height: "300px",
                    width: typeof width === 'number' ? width + 'px' : width
                }}
            >

      </div>
虚拟 dom (推荐使用)
import * as echarts from 'echarts'
const PieChart = defineComponent({
    name: 'PieChart',
    props,
    setup(props) {
        const pieChartRef: Ref<HTMLDivElement | null> = ref(null)

        const top10 = () => {
            return props.data.length>=10 ? props.data.slice(0,10) : props.data
        }

        const option = {
            title: {
                text: '分组聚合 Top 10',
                left: 'center',
                textStyle: {
                   color:'white'
                },
            },
            tooltip: {
                trigger: 'item',
                backgroundColor: '#fff'
            },
            legend: {
                bottom: '0%',
                left: 'center',
                textStyle:{
                    fontSize: 16,
                    color: 'white',
                    fontWeight: 'bold'
                }
            },
            series: [
                {
                    type: 'pie',
                    radius: ['35%', '60%'],
                    center: ['50%', '40%'],
                    avoidLabelOverlap: false,
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: 30,
                            fontWeight: 'bolder',
                            color: 'white'
                        }
                    },
                    label: {
                        show: false,
                        position: 'center'
                    },
                    labelLine: {
                        show: false
                    },
                    data: top10()
                }
            ]
        }

        let chart:Ref<ECharts | null>  = ref(null)
        const init = () => {
            chart.value = echarts.init(pieChartRef.value)
            chart.value.setOption(option)
        }


        const resize = throttle(() => {
            chart && chart.value.resize()
        }, 20)


        watch(
            () => props.data,
            () => {
                option.series[0].data= top10()
                chart.value.setOption(option)
            }
        )

        onMounted(() => {
            init()
            addEventListener('resize', resize)
        })


        return { pieChartRef }
    },
    render() {
        const { height, width } = this
        // console.log(`pie prop height:${height}, width:${width}`)
        return (
            // height: typeof height === 'number' ? height + 'px' : height,
            // width: typeof width === 'number' ? width + 'px' : width
            <div
                ref='pieChartRef'
                id={'myChart'}
                style={{
                    height: "300px",
                    width: typeof width === 'number' ? width + 'px' : width
                }}
            >

            </div>
        )
    }
})

三种与 Vue3 集成方式

单组件
import { onMounted } from "vue";
import * as echarts from 'echarts'
export default {
  name: "data_page",
  setup() {
    onMounted(() => {//需要获取到element,所以是onMounted的Hook
      let myChart = echarts.init(document.getElementById("customerChart"));
      // 绘制图表
      myChart.setOption({
        title: { text: "总用户量" },
        tooltip: {},
        xAxis: {
          data: ["12-3", "12-4", "12-5", "12-6", "12-7", "12-8"],
        },
        yAxis: {},
        series: [
          {
            name: "用户量",
            type: "line",
            data: [5, 20, 36, 10, 10, 20],
          },
        ],
      });
      window.onresize = function () {//自适应大小
        myChart.resize();
      };
    });
  },
  components: {},
  mounted() {},
};
全局 provide

在 App.vue种注入

<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import { useOsTheme, darkTheme ,GlobalThemeOverrides} from 'naive-ui'
import * as echarts from 'echarts'

provide('ec',echarts)//provide

</script>

<template>

  <NConfigProvider :theme="{useOsTheme}"  :theme-overrides="themeOverrides">
    <n-global-style/>
    <NMessageProvider>
    <router-view/>
    </NMessageProvider>
  </NConfigProvider>
</template>

<style lang="scss" scoped>

</style>

在组件中使用,这种方式可能会出现不能识别类型警告,需要加@ts-ignore

let echarts = inject("ec");//引入

            // @ts-ignore
            chart.value = echarts.init(pieChartRef.value)
全局挂载(推荐使用)

main.ts中配置如下:

import App from './App.vue'
import { createApp } from 'vue'
import './style.css'
//  echarts
import * as echarts from 'echarts'

const pinia = createPinia() 
pinia.use(piniaPluginPersistedstate) 

const app = createApp(App)
// 挂载 echarts
app.config.globalProperties.echarts = echarts

app.mount('#app')

在 tsx 页面中使用

        const globalProperties = getCurrentInstance()?.appContext.config.globalProperties
        let chart:Ref<ECharts | null>  = ref(null)
        const init = () => {
            chart.value = globalProperties?.echarts.init(pieChartRef.value)
            chart.value.setOption(option)
        }

<think>嗯,用户想知道在Vue3中如何集成和使用ECharts。首先,我需要回忆一下EChartsVue3的基本知识。ECharts是一个基于JavaScript的可视化库,而Vue3使用的是组合式API,可能与Vue2的集成方式有所不同。 首先,用户可能需要安装ECharts。通常,通过npm或yarn安装echarts包。然后,在Vue组件中引入它。但考虑到Vue3的生命周期钩子,比如onMounted,需要确保在组件挂载后再初始化图表。 接下来,用户可能需要将ECharts实例绑定到DOM元素上。在Vue3中,可以使用ref来引用DOM元素。例如,在模板中创建一个div,并给它一个ref属性,然后在setup函数中使用这个ref来获取DOM节点,并在onMounted钩子中初始化图表。 另外,可能需要考虑响应式的问题。比如,当组件的数据变化时,图表需要更新。这时候可能需要使用watchEffect或watch来监听数据变化,并更新图表的配置。 还有,为了优化性能,应该在组件卸载时销毁ECharts实例,避免内存泄漏。这时候可以使用onUnmounted生命周期钩子来调用echartsInstance.dispose()方法。 可能还需要封装一个可复用的ECharts组件,这样在多个地方使用时更方便。这涉及到通过props传递配置项,并在组件内部处理图表的大小调整,比如监听窗口resize事件,调用echartsInstance.resize()方法。 需要注意的是,在Vue3中使用组合式API时,所有的响应式变量和生命周期钩子都需要从vue中导入,比如import { ref, onMounted, onUnmounted, watch } from &#39;vue&#39;。 另外,可能还需要处理ECharts的按需加载,以减小打包后的体积。这可以通过使用官方的按需导入插件来实现,比如使用import * as echarts from &#39;echarts/core&#39;,然后按需引入需要的组件。 最后,用户可能希望看到具体的代码示例,包括安装步骤、基本集成方法和高级用法。比如,如何创建一个折线图,如何处理动态数据更新,如何封装组件等。 总结一下,步骤大致是:安装ECharts、在组件中引入、使用ref绑定DOM、在onMounted中初始化图表、处理响应式更新、销毁实例,以及可能的组件封装和优化措施。同时,需要确保代码符合Vue3的组合式API写法,并处理可能出现的错误和性能问题。</think>### 在Vue3集成和使用ECharts的完整指南 #### 1. 安装ECharts 通过npm或yarn安装核心库: ```bash npm install echarts --save # 或 yarn add echarts ``` #### 2. 基础集成 ```vue <template> <div ref="chartContainer" style="width: 600px; height: 400px;"></div> </template> <script setup> import { ref, onMounted, onUnmounted } from &#39;vue&#39;; import * as echarts from &#39;echarts&#39;; const chartContainer = ref(null); let chartInstance = null; // 初始化图表配置 const initChart = () => { const option = { xAxis: { type: &#39;category&#39;, data: [&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;] }, yAxis: { type: &#39;value&#39; }, series: [{ data: [820, 932, 901], type: &#39;line&#39; }] }; chartInstance.setOption(option); }; onMounted(() => { chartInstance = echarts.init(chartContainer.value); initChart(); window.addEventListener(&#39;resize&#39;, chartInstance.resize); }); onUnmounted(() => { window.removeEventListener(&#39;resize&#39;, chartInstance.resize); chartInstance.dispose(); }); </script> ``` #### 3. 响应式数据绑定 ```vue <script setup> import { watch } from &#39;vue&#39;; const props = defineProps({ chartData: Array }); watch(() => props.chartData, (newVal) => { chartInstance.setOption({ series: [{ data: newVal }] }); }); </script> ``` #### 4. 封装可复用组件 创建`BaseChart.vue`: ```vue <template> <div ref="chartEl" :style="{ width, height }"></div> </template> <script setup> import { defineProps } from &#39;vue&#39;; defineProps({ width: { type: String, default: &#39;100%&#39; }, height: { type: String, default: &#39;400px&#39; }, option: { type: Object, required: true } }); // 复用基础逻辑 // (包含初始化、响应式更新、销毁等代码) </script> ``` #### 5. 高级优化 - **按需加载**: ```javascript import * as echarts from &#39;echarts/core&#39;; import { LineChart } from &#39;echarts/charts&#39;; import { GridComponent, TooltipComponent } from &#39;echarts/components&#39;; echarts.use([LineChart, GridComponent, TooltipComponent]); ``` - **自动resize**: ```javascript const handleResize = () => chartInstance.resize(); onMounted(() => { window.addEventListener(&#39;resize&#39;, handleResize); }); onUnmounted(() => { window.removeEventListener(&#39;resize&#39;, handleResize); }); ``` #### 6. 最佳实践 1. 在服务端渲染(SSR)场景下使用`vue-echarts`官方适配库 2. 大数据量时启用`dataZoom`或使用`dataset`优化 3. 通过`showLoading`提升用户体验 4. 使用`theme`对象统一管理样式配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值