Vue3自定義Echars組件附帶全局配置方式
更新時(shí)間:2024年03月11日 09:15:58 作者:Circle_Key
這篇文章主要介紹了Vue3自定義Echars組件附帶全局配置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
Vue3自定義Echars組件附帶全局配置
<template> <div ref="chart" :id="id" :class="className" :style="{ height: height, width: width }"></div> </template> <script setup> import { ref, reactive, toRefs, onMounted, onBeforeUnmount,watch } from 'vue' import * as echarts from 'echarts'; // 傳遞參數(shù) const props = defineProps({ className: { type: String, default: 'chart' }, id: { type: String, default: 'chart' }, width: { type: String, default: '100%' }, height: { type: String, default: '280px' }, options: { type: Object, default: () => { } } }) const chart = ref(null); const createChart = () => { const myChart = echarts.init(chart.value); chart.value = echarts.init(chart.value, 'tdTheme') myChart.setOption(props.options,true); // chart.value.setOption(props.options, true) window.addEventListener("resize", () => { chart.value.resize() }) }; watch(() => props.options, (options) => { if (chart.value) { // 設(shè)置true清空echart緩存 chart.value.setOption(options, true) } }, { deep: true }) onMounted(() => { createChart(); }); onBeforeUnmount(() => { window.removeEventListener("resize", () => { chart.value.resize() }) chart.value.dispose() chart.value = null }) </script>
import Echart from './components/echart/index.vue' import echarts from 'echarts' const app = createApp(App) // 將echarts掛載到全局對象上 app.config.globalProperties.$echarts = echarts // 注冊全局組件 app.component('Echart', Echart)
案列
<template> <div ref="chart" style="width: 600px; height: 400px;"></div> </template> <script setup> import { ref, onMounted } from 'vue'; import * as echarts from 'echarts'; const chart = ref(null); const createChart = () => { const myChart = echarts.init(chart.value); myChart.setOption({ xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [{ data: [120, 200, 150, 80, 70, 110, 130], type: 'bar' }] }); }; onMounted(() => { createChart(); }); </script>
vue3封裝echarts組件
在開發(fā)項(xiàng)目過程中需要封裝echarts組件,方便多次使用,以下是封裝的詳細(xì)過程。
前置動(dòng)作:安裝echarts以及resize-observer-polyfill插件
- 新建echarts.ts文件
import * as echarts from "echarts/core"; /** * 這里按需引入使用到的圖表類型 */ import { BarChart, LineChart, type LineSeriesOption, PieChart, type PieSeriesOption } from "echarts/charts"; /** * 這里按需引入使用到的配置 * 特別地 包括MarkPoint markLine等這些也要單獨(dú)使用 不然在圖表中無法顯示 */ import { LegendComponent, type LegendComponentOption, TitleComponent, // 組件類型的定義后綴都為 ComponentOption type TitleComponentOption, TooltipComponent, type TooltipComponentOption, GridComponent, type GridComponentOption, DataZoomComponent, type DataZoomComponentOption, // 數(shù)據(jù)集組件 DatasetComponent, type DatasetComponentOption, // 標(biāo)記組件 MarkAreaComponent, type MarkAreaComponentOption, MarkLineComponent, type MarkLineComponentOption, MarkPointComponent, type MarkPointComponentOption, // 內(nèi)置數(shù)據(jù)轉(zhuǎn)換器組件 (filter, sort) TransformComponent, } from "echarts/components"; import { LabelLayout, UniversalTransition } from "echarts/features"; import { CanvasRenderer } from "echarts/renderers"; import { ref, shallowRef, onMounted, onBeforeUnmount } from "vue"; import ResizeObserver from "resize-observer-polyfill"; import throttle from "lodash/throttle"; /** * 引入的配置通過 ComposeOption 來組合出一個(gè)只有必須組件和圖表的 Option 類型 */ export type ECOption = echarts.ComposeOption< | LineSeriesOption | PieSeriesOption | LegendComponentOption | TitleComponentOption | TooltipComponentOption | DataZoomComponentOption | GridComponentOption | DatasetComponentOption | MarkAreaComponentOption | MarkLineComponentOption | MarkPointComponentOption >; /** * 注冊按需引入的組件 */ echarts.use([ LegendComponent, TitleComponent, TooltipComponent, GridComponent, DataZoomComponent, DatasetComponent, MarkAreaComponent, MarkLineComponent, MarkPointComponent, TransformComponent, BarChart, LineChart, PieChart, LabelLayout, UniversalTransition, CanvasRenderer, ]); export default function useChart() { const canvasEl = shallowRef(); const myChart = shallowRef(); /** * 監(jiān)聽容器寬度變化或者瀏覽器窗口變化對echarts圖表進(jìn)行自動(dòng)展示 * 不用window.addEventListener("resize", resizeFn)的原因是這個(gè)方法只是監(jiān)聽瀏覽器窗口的不變化 * -對所在容器的大小變化不進(jìn)行監(jiān)聽 很難滿足開發(fā)場景的需求 */ const resizeObserver = ref<ResizeObserver>(); const bindResize = () => { const deboundResize = throttle(() => { myChart.value?.resize(); }, 500); resizeObserver.value = new ResizeObserver(() => { deboundResize(); // myChart.value?.resize(); }); resizeObserver.value.observe(canvasEl.value); }; // 解綁 resize const unbindResize = () => { resizeObserver.value?.unobserve(canvasEl.value); }; onMounted(() => { /** * 注冊echarts并開啟監(jiān)聽容器大小變化 */ myChart.value = echarts.init(canvasEl.value); bindResize(); }); onBeforeUnmount(() => { /** * 銷毀監(jiān)聽和echarts */ unbindResize(); myChart.value?.dispose(); myChart.value = null; }); return { myChart, canvasEl, }; }
- 頁面封裝
<template> <div> <div class="chart-container" :style="containerStyle"> <div v-show="dataEmptyFlag" class="chart-empty"> <span class="empty-title">暫無數(shù)據(jù)</span> </div> <div ref="canvasEl" :style="containerStyle" /> <div v-show="loading" class="chart-loading"><Spin /></div> </div> </div> </template> <script setup lang="ts"> import { Spin } from "ant-design-vue"; import { ref, watch } from "vue"; import useChart from "./useECharts"; import type { ECOption } from "./useECharts"; interface ChartProps { containerStyle?: any; loading?: boolean; dataEmptyFlag?: boolean; options?: ECOption; } const props = withDefaults(defineProps<ChartProps>(), { containerStyle: { height: "990px", width: "100%", }, loading: false, dataEmptyFlag: false, }); const { myChart, canvasEl } = useChart(); watch( () => props?.options, (cur) => { if (myChart) { /** * 這里繪制圖表前先清空上一次數(shù)據(jù) 否則有時(shí)候會(huì)出現(xiàn)數(shù)據(jù)殘余的情況 */ myChart.value.clear(); myChart.value.setOption(cur); } }, ); </script> <style scoped> .chart-container { position: relative; width: 100%; } .chart-loading { align-items: center; background-color: #ffffff; bottom: 0; display: flex; justify-content: center; left: 0; position: absolute; right: 0; top: 0; z-index: 1999; } .chart-empty { position: absolute; z-index: 1; left: 0; right: 0; top: 0; bottom: 0; color: #888; font-size: 14px; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; flex-direction: column; } .empty-title { font-size: 16px; font-weight: 500; color: #000; } </style>
- 組件調(diào)用
/** * 參入對應(yīng)的參數(shù)以及圖表配置項(xiàng) */ <anewCharts :loading="loading" :data-empty-flag="dataEmptyFlag" :containerStyle="chartStyle" :options="chartOptions"></anewCharts>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
您可能感興趣的文章:
相關(guān)文章
微信小程序如何像vue一樣在動(dòng)態(tài)綁定類名
這篇文章主要介紹了微信小程序如何像vue一樣在動(dòng)態(tài)綁定類名,文中給大家提到了vue與微信小程序的區(qū)別,需要的朋友可以參考下2018-04-04Vue3使用postcss-px-to-viewport實(shí)現(xiàn)頁面自適應(yīng)
postcss-px-to-viewport 是一個(gè) PostCSS 插件,它可以將 px 單位轉(zhuǎn)換為視口單位,下面我們就看看如何使用postcss-px-to-viewport實(shí)現(xiàn)頁面自適應(yīng)吧2024-01-01vue項(xiàng)目中的public、static及指定不編譯文件問題
這篇文章主要介紹了vue項(xiàng)目中的public、static及指定不編譯文件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03vue子組件封裝彈框只能執(zhí)行一次的mounted問題及解決
這篇文章主要介紹了vue子組件封裝彈框只能執(zhí)行一次的mounted問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03vue3中使用scss加上scoped導(dǎo)致樣式失效問題
這篇文章主要介紹了vue3中使用scss加上scoped導(dǎo)致樣式失效問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10