vue3+ts+echarts實現按需引入和類型界定方式
vue3+ts+echarts實現按需引入和類型界定
一直想系統學習一下echarts,無奈今天在引入上就犯瞭難,現記錄一下我的解決方案
為瞭減少體積和使用的便利,我想實現一個按需和全局的引入
本來是想在main.ts當中直接import * as echarts from 'echarts',然後把這個echarts掛載在app的實例上,但是以我現有的經驗,這可能要涉及到this的問題,vue3已經極力避免this的出現,所以在看瞭相關大神的文章之後,我決定在App.vue的界面進行引入,然後利用provide函數,將形成的echarts變量傳遞給其他的子頁面,這樣就能實現全局使用的問題
//App.vue import{provide} from 'vue' import * as echarts from 'echarts' provide("echarts",echarts) //其他子頁面中 import {inject} from 'vue' let echarts=inject<any>("echarts")
第二個問題是關於按需的問題,這裡我直接貼上官方的寫法,簡單看看就行
import * as echarts from 'echarts/core'; import { BarChart, // 系列類型的定義後綴都為 SeriesOption BarSeriesOption, LineChart, LineSeriesOption } from 'echarts/charts'; import { TitleComponent, // 組件類型的定義後綴都為 ComponentOption TitleComponentOption, TooltipComponent, TooltipComponentOption, GridComponent, GridComponentOption, // 數據集組件 DatasetComponent, DatasetComponentOption, // 內置數據轉換器組件 (filter, sort) TransformComponent } from 'echarts/components'; import { LabelLayout, UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; // 通過 ComposeOption 來組合出一個隻有必須組件和圖表的 Option 類型 type ECOption = echarts.ComposeOption< | BarSeriesOption | LineSeriesOption | TitleComponentOption | TooltipComponentOption | GridComponentOption | DatasetComponentOption >; // 註冊必須的組件 echarts.use([ TitleComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent, BarChart, LabelLayout, UniversalTransition, CanvasRenderer ]); const option: ECOption = { // ... };
以上很明顯引入瞭一些bar圖和line圖,並且引入以option為結尾的組件類型,此外還引入瞭一些title基礎組件和對應類型,並利用use的方法將其與核心的echarts對象進行整合,還規制瞭一個ECOption作為echarts配置對象的類型,這確實實現瞭按需引入,但是問題是按照我上面的寫法,provide不能傳遞type,所以我需要將類型和echarts分開寫到兩個文件裡。
首先看一下App.vue的文件中我是怎麼按需配置echarts的
//App.vue文件 // 我本來想在這裡引入echart import { provide } from 'vue'; import * as echarts from 'echarts/core'; import { BarChart, // 系列類型的定義後綴都為 SeriesOption LineChart } from 'echarts/charts'; import { TitleComponent, // 組件類型的定義後綴都為 ComponentOption TooltipComponent, GridComponent, // 數據集組件 DatasetComponent, // 內置數據轉換器組件 (filter, sort) TransformComponent } from 'echarts/components'; import { LabelLayout, UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; // 註冊必須的組件 echarts.use([ TitleComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent, BarChart, LineChart, LabelLayout, UniversalTransition, CanvasRenderer ]); // 把這個配置好的echartprovide出去 provide("echarts", echarts) // 把這個option的選項類型也provide出去,但是provide方法無法使用傳遞類型,那我這邊隻能放棄
其實就是把全部的類型都摘瞭出來,然後單獨寫到一個echart.d.ts的申明文件中去,以下是代碼
//echart.d.ts // 因為provide不能傳遞type的原因,我們將echart的option類型單獨抽取出來寫一個申明文件 // 1.我們引入瞭線圖和bar圖,所以這裡我們引入瞭兩者的類型 import { ComposeOption } from 'echarts/core'; import { BarSeriesOption, LineSeriesOption } from 'echarts/charts'; //2.引入組件,也就是option選項中的類型 import { // 組件類型的定義後綴都為 ComponentOption TitleComponentOption, TooltipComponentOption, GridComponentOption, // 數據集組件 DatasetComponentOption, } from 'echarts/components'; // 3.通過 ComposeOption 來組合出一個隻有必須組件和圖表的 Option 類型 type ECOption = ComposeOption< | BarSeriesOption | LineSeriesOption | TitleComponentOption | TooltipComponentOption | GridComponentOption | DatasetComponentOption >; // 4.將這個類型暴露出去 export { ECOption }
然後是具體使用的代碼
import { inject, onMounted } from 'vue'; // 引入我自定義的圖像option類型 import { ECOption } from '../echart' let echarts = inject<any>("echarts") // 將echart的創建,壓縮成一個方程 let echartInit = () => { // 將option選項抽離出來 let option: ECOption = { title: { text: 'ECharts 入門示例' }, tooltip: {}, xAxis: { data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子'] }, yAxis: {}, series: [ { name: '銷量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] } // echart圖標的繪制 var myChart = echarts.init(document.getElementById('chart')); myChart.setOption(option); } onMounted(() => { echartInit() })
就是我的解決方案
vue3按需引入echarts及使用
參考官方示例:Examples – Apache ECharts
1、安裝
npm install echarts --save
如果要使用3d類型的需要引入 echarts-gl(本文需要)
npm install echarts-gl --save
2、main.js
// 引入 echarts 核心模塊 import * as echarts from 'echarts/core'; // 引入 echarts-gl 模塊 import { GlobeComponent } from 'echarts-gl/components'; // 引入 Canvas 渲染器 import { CanvasRenderer } from 'echarts/renderers'; // 註冊必須的組件 echarts.use([GlobeComponent, CanvasRenderer]); app.config.globalProperties.$echarts = echarts; // 註意這行要在 const app = createApp(App) 之後
3、使用
<template> <div class="earth" ref="earth"> <div id="main" ref="earthMain"></div> </div> </template> <script> import { defineComponent, ref, onMounted, getCurrentInstance } from "vue"; import earthImg from "@/assets/img/earth.jpg" export default defineComponent({ name: "frontPage", components: {}, setup() { const { proxy } = getCurrentInstance(); // !!!! let echarts = proxy.$echarts; let earth = ref(null); let earthMain = ref(null); let earthChart; onMounted(() => { let height = earth.value.offsetWidth * 0.0625; earth.value.style.height = height + "rem"; initEarth(); }); window.addEventListener("resize", function(){ let height = earth.value.offsetWidth; height *= 0.0625; earth.value.style.height = height + "rem"; if(earthChart){ earthChart.resize(); } }) let initEarth = function(){ earthChart = echarts.init(earthMain.value); let option = { globe: { baseTexture: earthImg, displacementScale: 0.1, shading: 'realistic', light: { ambient: { intensity: 0.9 }, main: { intensity: 0.1 } }, viewControl: { autoRotate: true, autoRotateAfterStill: 0.1, // 0 不縮放 zoomSensitivity: 0 }, top: 0, left: 0, right: 0, bottom: 0 }, series: [] }; option && earthChart.setOption(option); } return { earth, earthMain } }, }); </script> <style lang="scss" scoped> .earth { max-height: 600px; >div{ width: 100%; height: 100%; max-width: 600px; max-height: 600px; } } </style>
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- react+typescript中使用echarts的實現步驟
- 原生echart和vue-echart的使用詳解
- 基於vue+echarts數據可視化大屏展示的實現
- vue3使用echart的兩種引入方式以及註意事項說明
- vue3.0+echarts實現立體柱圖