关于vue3:vue3-ts-echarts封装一个基础echarts组件

话不多说,间接上代码吧

新增一个MyCharts.vue文件,文件内容如下

<!--
/**
* Author: 前端小高
* Desc: MyCharts 图表组件
*/
-->

<template>
  <div :id="chartId" :style="getChartStyle"></div>
</template>

<script name="MyCharts" lang="ts" setup>
import {
  ref,
  shallowRef,
  computed,
  watch,
  onMounted,
  onBeforeUnmount,
  getCurrentInstance,
  PropType
} from 'vue'
import { debounce } from 'lodash'
const { proxy } = getCurrentInstance() as any

const props = defineProps({
  options: {
    type: Object,
    default: () => {
      return {}
    }
  },
  height: {
    type: Number,
    default: 300
  },
  // 是否不跟之前的传入值合并
  notMerge: {
    type: Boolean,
    default: true
  }
})

const getChartStyle = computed(() => {
  return {
    width: '100%',
    height: `${props.height}px`
  }
})

watch(
  () => props.options,
  () => {
    initChart()
  },
  {
    deep: true
  }
)

// 默认显示的图表配置数据
const defaultOptions = {
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Email', 'Union Ads']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Email',
      type: 'line',
      smooth: true,
      stack: 'Total',
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: 'Union Ads',
      type: 'line',
      smooth: true,
      stack: 'Total',
      data: [220, 182, 191, 234, 290, 330, 310]
    }
  ]
}

const getRandomStr = () => {
  const randomNumStr = String(Math.random()).split('.')[1]
  return randomNumStr
}

const chartId = ref('chart-id')
const getChartId = () => {
  const str = 'chart-id-' + getRandomStr()
  chartId.value = str
}

getChartId()

const resizeHandler = () => {
  eChartsRef.value.resize()
}

const resizeHandlerOrigin = debounce(resizeHandler, 500)

const eCharts = proxy.$ECharts
const eChartsRef = shallowRef<any>()
const initChart = () => {
  eChartsRef.value = eCharts.init(document.getElementById(chartId.value))
  let options = {}
  if (isEmptyObj(props.options)) {
    options = defaultOptions
  } else {
    options = props.options
  }
  eChartsRef.value.setOption(options, props.notMerge)
  window.addEventListener('resize', resizeHandlerOrigin)
}

const isEmptyObj = (obj) => {
  return typeof obj === 'object' && JSON.stringify(obj) === '{}'
}

onMounted(() => {
  initChart()
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandlerOrigin)
  eChartsRef.value.dispose()
})

watch(
  () => props.options,
  () => {
    initChart()
  },
  {
    deep: true
  }
)
</script>
<style lang="scss" scoped></style>

页面下援用组件及应用办法

<template>
    <my-charts></my-charts>
</template>

<script name="TestPage" lang="ts" setup>
    import MyCharts from  './MyCharts.vue'
</script>

预览成果如下

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理