最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Vue3項(xiàng)目中優(yōu)化使用ECharts的完整方案

 更新時(shí)間:2026年05月17日 15:33:00   作者:Pu_Nine_9  
在Vue3項(xiàng)目中使用 ECharts,如何做到按需打包、類型安全、響應(yīng)式適配、自動(dòng)銷毀?本文分享一套可直接落地的封裝方案,需要的朋友可以參考下

一、整體思路

  • 按需引入:只注冊(cè)項(xiàng)目中用到的圖表、組件、渲染器,減少打包體積。
  • 統(tǒng)一導(dǎo)出:封裝一個(gè) @/utils/echarts 模塊,導(dǎo)出配置好的 echarts 實(shí)例和完整類型。
  • 組合式函數(shù):編寫 useECharts hook,自動(dòng)處理 DOM 掛載、配置響應(yīng)式更新、窗口/元素尺寸適配、生命周期清理。

二、文件 1:@/utils/echarts/index.ts—— 按需引入并導(dǎo)出

// TODO: 二次封裝 ECharts 實(shí)例
import * as echarts from 'echarts/core'

// 引入使用的圖表
import {
  BarChart,
  LineChart,
  PieChart
} from 'echarts/charts'

// 系列組件
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  VisualMapComponent,
  GeoComponent
} from 'echarts/components'

// 功能增強(qiáng)模塊
import {
  LabelLayout,
  UniversalTransition
} from 'echarts/features'

// 渲染器
import { CanvasRenderer } from 'echarts/renderers'

// 注冊(cè)所有必須組件
echarts.use([
  // 圖表
  BarChart,
  LineChart,
  PieChart,
  // 組件
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  VisualMapComponent,
  GeoComponent,
  // 功能
  LabelLayout,
  UniversalTransition,
  // 渲染
  CanvasRenderer
])

// 導(dǎo)出類型
export * from '../../types'   // 這里指向你自己的全局類型文件,也可以直接導(dǎo)出 echarts 自帶類型

// 導(dǎo)出手動(dòng)封裝后的 echarts
export { echarts }

說明:如果你的項(xiàng)目沒有單獨(dú)的 ../../types,可以直接改為導(dǎo)出 ECharts 的官方類型:

export type { ECharts, EChartsOption } from 'echarts'

三、文件 2:@/utils/echarts/types.ts—— 統(tǒng)一的 EChartsOption 類型(可選)

/**
 * 從 echarts/core 導(dǎo)入 ComposeOption 和 ECharts 類型
 * ComposeOption 是 ECharts 提供的類型組合工具,用于創(chuàng)建包含多種組件和圖表類型的配置選項(xiàng)類型
 * ECharts 是 ECharts 實(shí)例的類型
 */
import type { ComposeOption } from 'echarts/core'

/**
 * 從 echarts/charts 導(dǎo)入圖表系列類型
 */
import type {
  BarSeriesOption,
  LineSeriesOption,
  PieSeriesOption
} from 'echarts/charts'

/**
 * 從 echarts/components 導(dǎo)入組件配置類型
 */
import type {
  TitleComponentOption,
  TooltipComponentOption,
  LegendComponentOption,
  GridComponentOption,
  VisualMapComponentOption,
  GeoComponentOption
} from 'echarts/components'

/**
 * 導(dǎo)出具體的圖表類型,方便在需要時(shí)單獨(dú)使用
 */
export type { ECharts } from 'echarts/core'
export type {
  BarSeriesOption,
  LineSeriesOption,
  PieSeriesOption
} from 'echarts/charts'

/**
 * 統(tǒng)一的 EChartsOption 類型
 * 使用 ComposeOption 組合所有需要的類型,創(chuàng)建一個(gè)完整的配置選項(xiàng)類型
 * 這樣可以獲得更好的類型提示和類型檢查
 */
export type EChartsOption = ComposeOption<
  | BarSeriesOption
  | LineSeriesOption
  | PieSeriesOption
  | TitleComponentOption
  | TooltipComponentOption
  | LegendComponentOption
  | GridComponentOption
  | VisualMapComponentOption
  | GeoComponentOption
>

說明:如果你的項(xiàng)目沒有單獨(dú)的類型文件,也可以直接使用 ECharts 官方導(dǎo)出的 EChartsOption,但上述手動(dòng)組合可以精確控制可用組件,避免類型提示中出現(xiàn)未注冊(cè)的組件。

四、文件 3:@/hooks/useECharts.ts—— 核心 Hook

import { ref, watch, onMounted, onUnmounted, unref, type Ref } from 'vue'
import { echarts } from '@/utils/echarts'
import type { EChartsOption, ECharts } from '@/utils/echarts'

/**
 * ECharts 圖表 Hook
 * 自動(dòng)初始化、響應(yīng)式更新配置、自動(dòng)銷毀、窗口自適應(yīng)
 *
 * @param elRef - 圖表掛載的 DOM 引用(可以是 Ref 或原生 DOM 元素)
 * @param option - 圖表配置項(xiàng)
 * @param autoResize - 是否自動(dòng)跟隨窗口大小變化,默認(rèn) true
 * @returns { chart, updateOption }
 */
export const useECharts = (
  elRef: Ref<HTMLElement | null> | HTMLElement | null | undefined,
  option: EChartsOption,
  autoResize = true
) => {
  const chart = ref<ECharts | null>(null)

  // 初始化圖表
  const initChart = () => {
    const dom = unref(elRef)
    if (!dom) return
    chart.value = echarts.init(dom)
    chart.value.setOption(option)
  }

  // 更新配置
  const updateOption = (newOption: EChartsOption) => {
    chart.value?.setOption(newOption)
  }

  // 監(jiān)聽配置變化
  watch(
    () => option,
    () => updateOption(option),
    { deep: true }
  )

  // 監(jiān)聽 DOM 元素變化
  let resizeObserver: ResizeObserver | null = null
  const resize = () => chart.value?.resize()

  watch(
    () => unref(elRef),
    (newEl) => {
      if (newEl) {
        initChart()
        if (autoResize) {
          resizeObserver?.disconnect()
          resizeObserver = new ResizeObserver(resize)
          resizeObserver.observe(newEl)
        }
      }
    },
    { immediate: true }
  )

  // 組件掛載
  onMounted(() => {
    initChart()
    if (autoResize) {
      window.addEventListener('resize', resize)
      const dom = unref(elRef)
      if (dom) {
        resizeObserver = new ResizeObserver(resize)
        resizeObserver.observe(dom)
      }
    }
  })

  // 組件卸載
  onUnmounted(() => {
    if (autoResize) {
      window.removeEventListener('resize', resize)
      resizeObserver?.disconnect()
    }
    chart.value?.dispose()
    chart.value = null
  })

  return {
    chart: chart.value,
    updateOption,
  }
}

五、使用示例

5.1 基礎(chǔ)用法

<template>
  <div ref="chartRef" style="width: 100%; height: 400px" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useECharts } from '@/hooks/useECharts'
import type { EChartsOption } from '@/utils/echarts'

const chartRef = ref<HTMLElement>()

const option: EChartsOption = {
  title: { text: '月度銷售趨勢(shì)' },
  tooltip: {},
  xAxis: { type: 'category', data: ['1月', '2月', '3月', '4月'] },
  yAxis: { type: 'value' },
  series: [{ type: 'line', data: [120, 200, 150, 80] }]
}

const { chart, updateOption } = useECharts(chartRef, option, true)

// 模擬動(dòng)態(tài)更新數(shù)據(jù)
setTimeout(() => {
  updateOption({
    series: [{ type: 'line', data: [300, 400, 250, 100] }]
  })
}, 3000)
</script>

5.2 響應(yīng)式 option 自動(dòng)更新

如果你的 option 是響應(yīng)式數(shù)據(jù)(比如從 API 獲取),且希望數(shù)據(jù)變化時(shí)圖表自動(dòng)更新,可以直接傳入一個(gè) refcomputed

<script setup>
import { ref } from 'vue'

const chartData = ref([120, 200, 150])
const option = computed(() => ({
  xAxis: { data: ['A', 'B', 'C'] },
  series: [{ type: 'bar', data: chartData.value }]
}))

const { chart } = useECharts(chartRef, option.value)
// 現(xiàn)在當(dāng) chartData 變化時(shí),option 會(huì)重新計(jì)算,并觸發(fā) watch 自動(dòng)調(diào)用 updateOption
</script>

5.3 手動(dòng)控制 resize

如果某些場(chǎng)景下不需要自動(dòng) resize(比如彈窗中的圖表),可以將第三個(gè)參數(shù)設(shè)為 false,然后手動(dòng)調(diào)用 updateOption 中的 resize 邏輯(需要擴(kuò)展 hook)。

六、方案優(yōu)缺點(diǎn)總結(jié)

優(yōu)點(diǎn)

  • 體積優(yōu)化:按需引入,避免打包所有 ECharts 組件。
  • 類型安全:完整的 TypeScript 支持。
  • 自動(dòng)適配:同時(shí)監(jiān)聽 window.resizeResizeObserver,覆蓋大部分場(chǎng)景。
  • 生命周期安全:組件卸載時(shí)自動(dòng)銷毀圖表實(shí)例,避免內(nèi)存泄漏。
  • 響應(yīng)式更新option 變化時(shí)自動(dòng)重繪,無需手動(dòng)調(diào)用。

待改進(jìn)點(diǎn)(可根據(jù)項(xiàng)目需求繼續(xù)完善)

  • 當(dāng)前 chart 返回值是 chart.value(非響應(yīng)式),建議改成 chart 本身的 ref,或提供 getChart 方法。
  • 缺少 ECharts 事件監(jiān)聽封裝(如 on('click'))。
  • 缺少 loading 狀態(tài)、錯(cuò)誤處理、主題切換等企業(yè)級(jí)進(jìn)階功能。

你可以在此基礎(chǔ)上按需擴(kuò)展,例如:

// 增加事件監(jiān)聽
const on = (event: string, handler: any) => chart.value?.on(event, handler)
// 增加 loading
const showLoading = () => chart.value?.showLoading()
const hideLoading = () => chart.value?.hideLoading()

七、結(jié)語(yǔ)

這套封裝已經(jīng)在多個(gè)中大型 Vue 3 項(xiàng)目中實(shí)踐,兼顧了靈活性、性能和開發(fā)體驗(yàn)。如果你正為 ECharts 集成發(fā)愁,不妨直接復(fù)制以上三個(gè)文件到你的項(xiàng)目中,再根據(jù)實(shí)際需求微調(diào)。

以上就是在Vue3項(xiàng)目中優(yōu)化使用ECharts的完整方案的詳細(xì)內(nèi)容,更多關(guān)于Vue3優(yōu)化使用ECharts的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解vuex持久化插件解決瀏覽器刷新數(shù)據(jù)消失問題

    詳解vuex持久化插件解決瀏覽器刷新數(shù)據(jù)消失問題

    這篇文章主要介紹了詳解vuex持久化插件解決瀏覽器刷新數(shù)據(jù)消失問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • vue-treeselect(適配Vue3.2)及Element-plus的TreeSelect組件使用

    vue-treeselect(適配Vue3.2)及Element-plus的TreeSelect組件使用

    這篇文章主要介紹了vue-treeselect(適配Vue3.2)及Element-plus的TreeSelect組件使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • vue前端重構(gòu)computed及watch組件通信等實(shí)用技巧整理

    vue前端重構(gòu)computed及watch組件通信等實(shí)用技巧整理

    這篇文章主要為大家介紹了vue前端重構(gòu)computed及watch組件通信等實(shí)用技巧整理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • vue新手入門出現(xiàn)function () { [native code] }錯(cuò)誤的解決方案

    vue新手入門出現(xiàn)function () { [native code]&nbs

    這篇文章主要介紹了vue新手入門出現(xiàn)function () { [native code] }錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • VUE+jszip如何實(shí)現(xiàn)下載多個(gè)文件導(dǎo)出為一個(gè)zip格式

    VUE+jszip如何實(shí)現(xiàn)下載多個(gè)文件導(dǎo)出為一個(gè)zip格式

    這篇文章主要介紹了VUE+jszip如何實(shí)現(xiàn)下載多個(gè)文件導(dǎo)出為一個(gè)zip格式方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Vue 2.X的狀態(tài)管理vuex記錄詳解

    Vue 2.X的狀態(tài)管理vuex記錄詳解

    這篇文章主要介紹了Vue 2.X的狀態(tài)管理vuex記錄的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家的理解和學(xué)習(xí)具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • 分離vue文件中css、js代碼的簡(jiǎn)單技巧

    分離vue文件中css、js代碼的簡(jiǎn)單技巧

    這篇文章主要給大家介紹了關(guān)于分離vue文件中css、js代碼的簡(jiǎn)單技巧,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 一文帶你搞懂Vue?Loader是如何工作的

    一文帶你搞懂Vue?Loader是如何工作的

    Vue?Loader?作為一個(gè)?webpack?的?Loader,扮演著將?.vue?文件轉(zhuǎn)化為瀏覽器可執(zhí)行代碼的角色,下面就跟隨小編一起深入了解Vue?Loader?的技術(shù)細(xì)節(jié)與工作機(jī)制吧
    2024-12-12
  • vue3整合SpringSecurity加JWT實(shí)現(xiàn)登錄認(rèn)證

    vue3整合SpringSecurity加JWT實(shí)現(xiàn)登錄認(rèn)證

    本文主要介紹了vue3整合SpringSecurity加JWT實(shí)現(xiàn)登錄認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • VUE安裝使用教程詳解

    VUE安裝使用教程詳解

    這篇文章主要介紹了安裝使用VUE的教程,本文給大家提到了遇到的問題原因分析及解決方法,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

台东市| 灵石县| 永丰县| 黑水县| 改则县| 惠水县| 招远市| 涿州市| 三台县| 白城市| 乌苏市| 五大连池市| 安西县| 长岛县| 教育| 连城县| 丽江市| 怀来县| 上栗县| 太和县| 南溪县| 陇川县| 温泉县| 宁蒗| 定襄县| 昌江| 道真| 墨玉县| 五家渠市| 海盐县| 东台市| 新绛县| 永福县| 望奎县| 临海市| 横山县| 通渭县| 聊城市| 志丹县| 桓台县| 穆棱市|