vue3+ts 之echarts的使用 以及 echarts 图表初始不渲染,代码改变之后才渲染

文章介绍了在Vue3+TS环境下按需引入Echarts并实现仪表盘图表的过程,包括设置图表样式、处理数据未返回时的显示问题,以及解决图表初次不渲染的问题。通过watcher监听props变化并动态设置图表选项,确保数据加载后正确显示。
摘要由CSDN通过智能技术生成


前言

项目环境使用的是 vben admin 框架,业务中想要在当前项目中使用一个 echarts 图表
项目语言使用的是 vue3+TypeScript


一、按需引入 ECharts 图表和组件

当前项目别的位置使用的有 echarts ,已经引入和安装过 echarts 了,所以这就不需要再重新 npm 安装 echarts,只需要按需引用我自己需要的就可以了
官方使用文档 : 按需引入 ECharts 图表和组件
在这里插入图片描述在项目中找到了这个文件 (我自己项目的存放路径是在 src\utils\lib\echarts.ts
在这里插入图片描述
我需要使用的图标是一个仪表盘,官方示例是长这个样子的

在这里插入图片描述
在这里插入图片描述这个图表的类型是 guage
按照官方所说的按需引入,我在原来的文件中的 import 和 use 中分别加上了 GuageChart (我是看别的图表是首字母大写后面加上 Chart 就也这么写了,猜对了~
在这里插入图片描述
在这里插入图片描述

引入到此就 OK 了

二、使用步骤

1.还是先上代码叭

<!--这里是关于满仓率的图表-->
<template>
  <div ref="chartRef" :style="{ width, height }"></div>
</template>
<script lang="ts" setup>
  import { Ref, ref, watch } from 'vue';
  import { useECharts } from '/@/hooks/web/useECharts';

  const props = defineProps({
    loading: Boolean, 
    width: {
      type: String as PropType<string>,
      default: '100%',
    },
    height: {
      type: String as PropType<string>,
      default: '300px',
    },
    ratio: Number,
  });

  const chartRef = ref<HTMLDivElement | null>(null);
  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  watch(
    () => props.loading,
    () => {
      if (props.loading) {
        return;
      }
      setOptions({
        tooltip: {
          formatter: '{a}<br/>{b} : {c}',
        },
        series: [
          {
            name: '满仓率',
            type: 'gauge',
            progress: {
              show: true,
            },
            detail: {
              valueAnimation: true,
              formatter: function (value) {
                if (!props.ratio) {
                  return '加载中';
                } else {
                  return props.ratio + '%';
                }
              },
              fontSize: 20,
            },
            data: [
              {
                value: props.ratio,
              },
            ],
          },
        ],
      });
    },
    { immediate: true },
  );
</script>

2. 上实现效果 ! ~

在这里插入图片描述

3. 代码分析

我是直接把一个图表封装到这个组件里了,这是个相对很简单的图表,只有关键性参数就是 data 中的那个 value,这个参数是从调用这个组件的位置传过来的

<!--父组件-->
          <Card size="default" :canExpan="false" :bordered="false">
            <Meta description="满仓率" />
            <RemainGuage :ratio="panelObj.fullPercent" /> 
          </Card>

在子组件中接收传过来的参数 ratio

// 子组件
  const props = defineProps({
    loading: Boolean, 
    width: {
      type: String as PropType<string>,
      default: '100%',
    },
    height: {
      type: String as PropType<string>,
      default: '300px',
    },
    ratio: Number, // 传过来的 ratio
  });

4. 遇到的问题以及解决方式

4.1 原本样式是直接将数字展示上去(如 : 31 ,业务希望展示的是 31%)

可以在 detail 的 formatter 配置项中配置期望的格式

    detail: {
      valueAnimation: true,
      formatter: '{value}%'
    },

4.2 页面初始化图表组件渲染的时候没数据导致页面中显示的是 undefined

会在下面展示数字的位置显示出大大的 undefined 字样
在这里插入图片描述
因为这个数据是从后端获取的,当响应数据没回来的时候会出大大的 undefined 字样,这样子页面也太不友好了,所以
希望当数据还没有回来的时候这里展示的是加载中的字样,当数据返回,再展示真实的百分比数据
在官方文档中可以看到 series-gauge.data.detail. formatter可以是 格式化函数或者字符串
在这里插入图片描述所以这里放进去一个函数

detail: {
   valueAnimation: true,
   formatter: function (value) {
     if (!value) {
       return '加载中';
     } else {
       return value + '%';
     }
   },
   fontSize: 20, // 这里是为了调整百分比字体的大小的
 },

4.3 echarts 图表初始不渲染,代码改变之后才渲染

图表的数据是父组件请求回来数据之后传过来的,但是传过来之后图表却没有渲染,发现代码改动重新保存后才会开始渲染(就是图表的动画才开始动起来)
在网上找到了一个有效的方式是在使用这个图表子组件的位置加上下面的这个 v-if
在这里插入图片描述
原因分析

这是和父子组件的生命周期有关系
以下来自大佬 喜欢星期六_ 的分析
在这里插入图片描述
可以看到在父组件mounted之前, 子组件已经挂载完毕, 引入情景就是无论你封装的 echarts子组件的渲染是放在 mounted() 还是 nextTick 中, 此时你父组件中的 mounted() 还未执行【因为我把数据请求都放在mounted中了】,所以此时渲染的 echarts是没有数据的,或者说你传过去的是空的数据, 就算你的options 中存在部分配置,可数据为空, 图表就会是空白,但是其实你去控制台去审查元素, canvas 标签是有的。

综上: 这种情况下你可以 通过 v-if 去判断, 当确实请求到数据,后再去传给子组件后渲染图表。

或者你也可以到 vue3 setup 中直接发请求【vue3 中 setup 所处生命周期为 beforeCreated 和 created 间, 这两个生命周期是位于子组件之前的】 或者 在 vue2 created() {} 中去发请求, 估计可以不需要 v-if 就可以 渲染出图表。

直接到 vue3 setup 中直接发请求可以成功渲染,不需要v-if,只是组件会需要使用 《suspense》 包裹。

以上,踩坑记录!!!


总结

上次使用 echarts 还是在上次 , 好久好久好久了啊,这次上来就 vben vue3 ts 就懵逼了,但是叭使用方式还都是大体一样的,就此记录 ~ 晚安

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Vue3 + TypeScript 中画 Echarts 环形图表,可以按照以下步骤进行: 1. 安装 EchartsVue-Echarts: ``` npm install echarts vue-echarts@5.0.0-beta.5 ``` 2. 在需要使用的组件中引入 EchartsVue-Echarts: ```typescript import { defineComponent, onMounted, ref } from 'vue' import * as echarts from 'echarts' import { use } from 'echarts/core' import { CanvasRenderer } from 'echarts/renderers' import { PieChart } from 'echarts/charts' import { LegendComponent, TooltipComponent } from 'echarts/components' import VueECharts from 'vue-echarts' use([CanvasRenderer, PieChart, LegendComponent, TooltipComponent]) export default defineComponent({ components: { VueECharts }, setup() { const chartRef = ref(null) const chart = ref<echarts.ECharts | null>(null) const options: echarts.EChartsOption = { title: { text: '环形图示例' }, tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' }, legend: { orient: 'vertical', left: 10, data: ['数据1', '数据2', '数据3', '数据4', '数据5'] }, series: [ { name: '访问来源', type: 'pie', radius: ['50%', '70%'], avoidLabelOverlap: false, label: { show: false, position: 'center' }, emphasis: { label: { show: true, fontSize: '30', fontWeight: 'bold' } }, labelLine: { show: false }, data: [ { value: 335, name: '数据1' }, { value: 310, name: '数据2' }, { value: 234, name: '数据3' }, { value: 135, name: '数据4' }, { value: 1548, name: '数据5' } ] } ] } onMounted(() => { if (chartRef.value) { chart.value = echarts.init(chartRef.value) chart.value.setOption(options) } }) return { chartRef, chart } } }) ``` 3. 在组件的模板中使用 Vue-Echarts 组件,并传入需要渲染的数据和 Echarts 实例: ```vue <template> <div> <vue-echarts :options="options" :auto-resize="true" :renderer="'canvas'" :chart="chartRef"></vue-echarts> </div> </template> ``` 这样就可以在 Vue3 + TypeScript 中画出一个简单的 Echarts 环形图表了。注意,在 setup 函数中,需要使用 `ref` 函数将 `chart` 和 `chartRef` 定义为响应式数据,并在 `onMounted` 钩子函数中初始Echarts 实例并设置选项。在模板中,需要将 `chartRef` 作为 `VueECharts` 组件的 `chart` 属性传入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值