vue3+echarts封装

222 阅读1分钟

vue3的hooks彻底把echarts的封装方式改变了。vue2只能传参到组件进行监听或者主动渲染,走vue3可以直接用hook抛出渲染函数。数据更新后调用渲染函数,传入需要渲染的数据配置即可。

/**
 *  封装echarts
 * @param hChartRef 绑定dom
 * @param getOption 返回一个echarts配置项
 * @returns {renderChart: (data: T) => void}/* 返回一个渲染函数
 * 渲染函数接收一个数据对象作为参数,并使用该对象更新echarts实例的配置项。
 */
export const useHysChart = <T>(hChartRef: Ref, getOption: (data: T) => any): { renderChart: (data: T) => void; hideLoading: () => void; showLoading: () => void } => {
  // 初始化echarts实例
  let echartsInstance: EChartsType | null = null

  onMounted(() => {
    echartsInstance = init(hChartRef.value, 'hys')
  })

  const renderChart = (data: T): void => {
    const options = getOption(data)
    echartsInstance?.setOption(options)
  }
  const showLoading = (): void => {
    echartsInstance?.showLoading({
      text: '努力加载中...',
      textColor: '#fff',
      maskColor: 'rgba(0, 0, 0, 0.1)',
      fontSize: 20
    })
  }
  const hideLoading = (): void => {
    echartsInstance?.hideLoading()
  }

  useDomResize(hChartRef, () => echartsInstance?.resize({ animation: { duration: 300 } }))

  return {
    renderChart,
    showLoading,
    hideLoading
  }
}

使用方式也无需再额外新增组件包裹,只需要指定一个dom,传入ref即可

<!--市场活跃度-->
<template>
  <h-card>
    <template #h-header>活跃度</template>
    <template #h-body>
      <div ref="hChartRef" style="width: 100%; height: 100%"></div>
    </template>
  </h-card>
</template>

<script setup lang="ts">
  import HCard from '@/components/HCard/h-card.vue'
  import { useHysChart } from '@/hooks/useCharts'
  import { getOptions } from '@/components/HCharts/chartOptions/hBarOption1'
  import { onMounted, ref } from 'vue'
  import { getDemandResponse } from '@/api'
  import { useOrg } from '@/hooks/useOrg'

  const hChartRef = ref<HTMLDivElement>()
  const { renderChart, showLoading, hideLoading } = useHysChart(hChartRef, getOptions)

  onMounted(() => {
    hInit()
  })
  // 业务代码
  const hInit = (): void => {
    showLoading()
    getDemandResponse({
      orgNo: orgNo.value,
      type: '00'
    })
      .then(res => {
        renderChart({
          seriesData: [res.data.allConsNoList, res.data.responseList],
          xData: res.data.orgNameList
        })
      })
      .finally(() => {
        hideLoading()
      })
  }

  // ----监听组织机构变化----
  const { orgNo } = useOrg(hInit)
</script>

getOptions函数就是实际写echarts配置的地方,配置项抽离也极易在各个项目中拷贝复用。