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()
})

以上就是我的解决方案,非科班出身,术语上可能有错误,欢迎讨论建议 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
首先,你要安装 EchartsVue3,可以通过以下命令进行安装: ``` npm install echarts vue@next ``` 然后,在你的 Vue3 项目中,创建一个组件,例如 `DoubleLineChart.vue`,并在模板中添加一个 div 元素,用于渲染 Echarts 图表: ```html <template> <div ref="chart" style="height: 500px"></div> </template> ``` 在组件中,你引入 Echarts 和定义图表的配置选项: ```typescript import { defineComponent } from 'vue'; import * as echarts from 'echarts'; export default defineComponent({ name: 'DoubleLineChart', props: { data: { type: Object, required: true, }, }, mounted() { const chart = echarts.init(this.$refs.chart as HTMLDivElement); const option = { // 配置选项 }; chart.setOption(option); }, }); ``` 在配置选项中,你要定义两个 y 轴,分别对应两条折线: ```typescript const option = { tooltip: { trigger: 'axis', }, legend: { data: ['销量', '访问量'], }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true, }, xAxis: { type: 'category', boundaryGap: false, data: this.data.xData, }, yAxis: [ { type: 'value', name: '销量', axisLabel: { formatter: '{value} 件', }, }, { type: 'value', name: '访问量', axisLabel: { formatter: '{value} 次', }, }, ], series: [ { name: '销量', type: 'line', yAxisIndex: 0, data: this.data.y1Data, }, { name: '访问量', type: 'line', yAxisIndex: 1, data: this.data.y2Data, }, ], }; ``` 其中,`data` 属性是一个对象,包含了 x 轴和两个 y 轴的数据: ```typescript export default defineComponent({ name: 'DoubleLineChart', props: { data: { type: Object, required: true, }, }, mounted() { const chart = echarts.init(this.$refs.chart as HTMLDivElement); const option = { tooltip: { trigger: 'axis', }, legend: { data: ['销量', '访问量'], }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true, }, xAxis: { type: 'category', boundaryGap: false, data: this.data.xData, }, yAxis: [ { type: 'value', name: '销量', axisLabel: { formatter: '{value} 件', }, }, { type: 'value', name: '访问量', axisLabel: { formatter: '{value} 次', }, }, ], series: [ { name: '销量', type: 'line', yAxisIndex: 0, data: this.data.y1Data, }, { name: '访问量', type: 'line', yAxisIndex: 1, data: this.data.y2Data, }, ], }; chart.setOption(option); }, }); ``` 最后,在父组件中,你可以使用 `DoubleLineChart` 组件,并传递数据给它: ```html <template> <div> <double-line-chart :data="chartData" /> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import DoubleLineChart from '@/components/DoubleLineChart.vue'; export default defineComponent({ name: 'App', components: { DoubleLineChart, }, data() { return { chartData: { xData: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], y1Data: [120, 200, 150, 80, 70, 110, 130], y2Data: [220, 180, 290, 130, 220, 200, 150], }, }; }, }); </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值