1.bar.ts

// 我是柱状图
import * as  echarts from 'echarts'
require('echarts/lib/chart/line')
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function drawChartBar(param, element) {
  let myChart= echarts.getInstanceByDom(element); //有的话就获取已有echarts实例的DOM节点。
  if (myChart== null) { // 如果不存在,就进行初始化。
    myChart= echarts.init(element);
  }
  myChart.clear();
  //   配置项
  const pzx = {
    // 图例
    legend: {
      data: param.legend.data ? param.legend.data : [], // 图例的值 示例: ['星期一', '星期二']
      show: param.legend.show ? param.legend.show : false, // 控制图例显示
      bottom: param.legend.bottom || param.legend.bottom === 0 || param.legend.bottom === '0' ? param.legend.bottom : '', // 控制图例底部如果图例在底部这个参数为0
      right: param.legend.right || param.legend.right === 0 || param.legend.right === '0' ? param.legend.right : '', // 控制图例右部如果图例在右部这个参数为0
      top: param.legend.top || param.legend.top === 0 || param.legend.top === '0' ? param.legend.top : '', // 控制图例顶部部如果图例在顶部这个参数为0
      left: param.legend.left || param.legend.left === 0 || param.legend.left === '0' ? param.legend.left : '', // 控制图例右部如果图例在右部这个参数为0
      type: 'scroll'
    },
    grid: {
      containLabel: true,
      bottom: param.grid.bottom || param.grid.bottom === 0 || param.grid.bottom === '0' ? param.grid.bottom : '', // 控制图例底部如果图例在底部这个参数为0
      right: param.grid.right || param.grid.right === 0 || param.grid.right === '0' ? param.grid.right : '', // 控制图例右部如果图例在右部这个参数为0
      top: param.grid.top || param.grid.top === 0 || param.grid.top === '0' ? param.grid.top : '', // 控制图例顶部部如果图例在顶部这个参数为0
      left: param.grid.left || param.grid.left === 0 || param.grid.left === '0' ? param.grid.left : '' // 控制图例右部如果图例在右部这个参数为0
    },
    // y轴 这边暂时按照1个y轴配置
    yAxis: {
      type: 'value',
      show: param.yAxis.show ? param.yAxis.show : false,
      name: param.yAxis.name ? param.yAxis.name : '',
      nameLocation: param.yAxis.nameLocation ? param.yAxis.nameLocation : 'end', // y轴的name位置start,middle,end
      axisLine: {
        show: param.yAxis.axisLine ? (param.yAxis.axisLine.show ? param.yAxis.axisLine.show : true) : true,
        lineStyle: {
          color: param.yAxis.axisLine ? (param.yAxis.axisLine.color ? param.yAxis.axisLine.color : '#CCCCCC') : '#CCCCCC', // y轴线条颜色支持渐变色
          type: param.yAxis.axisLine ? (param.yAxis.axisLine.type ? param.yAxis.axisLine.type : 'solid') : 'solid' // 线条类型,默认solid,'dashed','dotted'
        }
      },
      axisLabel: {
        inside: false,
        color: '#333333'
      },
      splitLine: {
        show: param.yAxis.splitLine ? (param.yAxis.splitLine.show ? param.yAxis.splitLine.show : false) : false,
        lineStyle: {
          type: param.yAxis.splitLine ? (param.yAxis.splitLine.type ? param.yAxis.splitLine.type : 'dashed') : 'dashed'
        }
      }
    },
    // x轴
    xAxis: {
      type: 'category',
      data: param.xAxis.data,
      show: param.xAxis.show ? param.xAxis.show : true,
      position: param.xAxis.position ? param.xAxis.position : 'bottom', // x轴位置 top,bottom
      name: param.xAxis.name ? param.xAxis.name : '', // x轴名称
      nameTextStyle: {
        color: param.xAxis.nameTextStyle ? (param.xAxis.nameTextStyle.color ? param.xAxis.nameTextStyle.color : '#333333') : '#333333', // x轴的字体颜色
        fontSize: param.xAxis.nameTextStyle ? (param.xAxis.nameTextStyle.fontSize ? param.xAxis.nameTextStyle.fontSize : '12') : '12' // x轴的字体大小
      },
      axisLine: {
        show: param.xAxis.axisLine ? (param.xAxis.axisLine.show ? param.xAxis.axisLine.show : true) : true,
        lineStyle: {
          color: param.xAxis.axisLine ? (param.xAxis.axisLine.color ? param.xAxis.axisLine.color : '#CCCCCC') : '#CCCCCC', // y轴线条颜色支持渐变色
          type: param.xAxis.axisLine ? (param.xAxis.axisLine.type ? param.xAxis.axisLine.type : 'solid') : 'solid' // 线条类型,默认solid,'dashed','dotted'
        }
      },
      axisTick: {
        // 刻度相关
        show: param.xAxis.axisTick ? (param.xAxis.axisTick.show ? param.xAxis.axisTick.show : true) : true,
        alignWithLabel: param.xAxis.axisTick ? (param.xAxis.axisTick.alignWithLabel ? param.xAxis.axisTick.alignWithLabel : false) : false
      },
      axisLabel: param.xAxis.axisLabel? param.xAxis.axisLabel : {
        inside: false,
        color: '#333333',
      },
      splitLine: {
        show: param.xAxis.splitLine ? (param.xAxis.splitLine.show ? param.xAxis.splitLine.show : false) : false,
        lineStyle: {
          type: param.xAxis.splitLine ? (param.xAxis.splitLine.type ? param.xAxis.splitLine.type : 'dashed') : 'dashed'
        }
      }
    },
    // series
    series: param.series ? param.series : [],
    // color
    color: param.color ? param.color : [],
    dataZoom: [
      {
        id: 'dataZoomX',
        type: 'inside',
        xAxisIndex: [0],
        end: param.dataZoom.end ? param.dataZoom.end : 100,
        filterMode: 'filter'
      }
    ],
    tooltip: {
      show: true,
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    }
  }
  if (pzx.color.length === 0) {
    delete pzx.color
  }
  if (!pzx.legend.right && pzx.legend.right !== 0 && pzx.legend.right !== '0') {
    delete pzx.legend.right
  }
  if (!pzx.legend.left && pzx.legend.left !== 0 && pzx.legend.left !== '0') {
    delete pzx.legend.left
  }
  if (!pzx.legend.top && pzx.legend.top !== 0 && pzx.legend.top !== '0') {
    delete pzx.legend.top
  }
  if (!pzx.legend.bottom && pzx.legend.bottom !== 0 && pzx.legend.bottom !== '0') {
    delete pzx.legend.bottom
  }
  if (!pzx.grid.right && pzx.grid.right !== 0 && pzx.grid.right !== '0') {
    delete pzx.grid.right
  }
  if (!pzx.grid.left && pzx.grid.left !== 0 && pzx.grid.left !== '0') {
    delete pzx.grid.left
  }
  if (!pzx.grid.top && pzx.grid.top !== 0 && pzx.grid.top !== '0') {
    delete pzx.grid.top
  }
  if (!pzx.grid.bottom && pzx.grid.bottom !== 0 && pzx.grid.bottom !== '0') {
    delete pzx.grid.bottom
  }
  myChart.setOption(pzx)
  return myChart
}

2.使用
2.1 这是子组件

<!-- 我是BI的echarts的封装 -->
<template>
 <div class='con BIDataEcharts'>
  <el-row :gutter="20">
      <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
        <div class="el-col-div" :style="{
          boxShadow: `var(--el-box-shadow-lighter)`,
        }">
          <p>{{ new Date().getFullYear() }} Project Stage</p>
          <div class="chart08 chart"></div>
        </div>
      </el-col>
    </el-row>
 
 </div>
</template>
<script lang='ts' setup>
/** 接口 */
export interface propsForm {
  projectStage:{
    [propName: string]: any // 添加任意属性
  },
 
}
import { reactive, toRefs, defineProps, withDefaults, defineEmits, ref, watch, onMounted, nextTick, onBeforeUnmount } from 'vue';
import useCurrentInstance from '@/api/useCurrentInstance';
import { drawChartBar } from '@/api/echartsFunction/bar';
import * as  echarts from 'echarts'
const { proxy } = useCurrentInstance()
const emit = defineEmits(['searchFunction'])
/** prop */
const props = withDefaults(defineProps<propsForm>(), {
  projectStage:() => {
    return {}
  },
})
/** 计算属性*/
const state = reactive({
  mycharts01: null,
  resizefun01: null,

})
const { mycharts01, resizefun01 } = toRefs(state)
/** 监听 */
watch(() => props.projectStage, val => {
  getChart('1', val)
}, { deep: true })


watch(() => proxy.$store.state.currentTab, () => {
  // 解决tab切换echarts不会重新渲染
  nextTick(()=>{
    getChart("1", props.projectStage)

  })
})
/** 生命周期 */
onMounted(() => {
  getChart("1", props.projectStage)
 
  /** ****自动适应缩放模块******/
  // ECHART01
  resizefun01.value = () => {
    if (mycharts01.value) {
      // 防止重复性渲染
      mycharts01.value.resize()
    } else {
      echarts.init(document.querySelector(".chart08")).resize()
    }
  }
  window.addEventListener('resize', resizefun01.value)

 
})
onBeforeUnmount(() => {
  // ----------这个是用来释放图表 ECHART01
  const dcharts08 = echarts.getInstanceByDom(document.querySelector(".chart08"))
  if (dcharts08) {
    echarts.dispose(dcharts08)
    // 这是调用ie内存回收
    const _window = window as any
    if (_window.CollectGarbage) {
      _window.CollectGarbage()
    }
  }

})
/** methods */
const getChart = (type, val) => {
  if (type === '1' && document.querySelector(".chart08").clientWidth) {
    const dcharts01 = echarts.getInstanceByDom(document.querySelector(".chart08"))
    if (dcharts01) {
      echarts.dispose(dcharts01)
      // 这是调用ie内存回收
      const _window = window as any
      if (_window.CollectGarbage) {
        _window.CollectGarbage()
      }
    }
    mycharts01.value = drawChartPie(val, document.querySelector(".chart08"))
  }
}
</script>
<style lang="scss" scoped>
.BIDataEcharts {
  width: 100%;
  height: 100%;
  padding:30px 20px;
  box-sizing: border-box;
  .chart {
    width: 100%;
    height: 400px;
  }

  .el-col-div{
    padding:20px;
    box-sizing: border-box;
    margin-bottom: 20px;
    border-radius: 4px;
    p{
      margin-top:0px;
      border-left: solid 4px #36ad6a;
      text-indent: 1em;
    }
  }
}
</style>

3.父组件

<!-- 我是BI页面 -->
<template>
  <div>
    <div>
      <BIDataEcharts :projectStage="projectStage" :mountingSystem="mountingSystem" :systemAverageCost="systemAverageCost" :budgetForcast="budgetForcast" />
    </div> 
  </div>
  </div>
</template>
<script lang='ts' setup>
/** 接口 */
import * as  echarts from 'echarts';

import { reactive, toRefs, ref, nextTick, onMounted, onBeforeUnmount } from 'vue';
import wordMap from "@/api/word";
import useCurrentInstance from '@/api/useCurrentInstance';
import moment from 'moment';
import BIDataEcharts from './components/BIDataEcharts.vue';  // 这个就是上面的子组件
require('echarts/lib/chart/line')
const { proxy } = useCurrentInstance()
const chartP = ref();

/** prop */

/** 计算属性*/
/** data */
const state = reactive({
  systemAverageCost: {
      legend: {
        data: [], // 图例的值 示例: ['星期一', '星期二']  // -----这个是必须的
        show: true, // 控制图例显示
        bottom: '', // 控制图例底部如果图例在底部这个参数为0
        right: '0', // 控制图例右部如果图例在右部这个参数为0
        top: '0', // 控制图例顶部部如果图例在顶部这个参数为0
        left: '' // 控制图例右部如果图例在右部这个参数为0
      },
      // y轴 这边暂时按照1个y轴配置
      yAxis: {
        type: 'value',
        show: true,
        name: '',
        nameLocation: 'end', // y轴的name位置start,middle,end
        axisLine: {
          show: false,
          color: '#ffffff', // y轴线条颜色支持渐变色
          type: 'solid' // 线条类型,默认solid,'dashed','dotted'
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed'
          }
        }
      },
      // x轴
      xAxis: {
        type: 'category',
        data: [], // -----这个是必须的
        show: true,
        position: 'bottom', // x轴位置 top,bottom
        name: '', // x轴名称
        nameTextStyle: {
          color: '#333333', // x轴的字体颜色
          fontSize: '12' // x轴的字体大小
        },
        axisLine: {
          show: true,
          color: '#CCCCCC', // y轴线条颜色支持渐变色
          type: 'solid' // 线条类型,默认solid,'dashed','dotted'
        },
        axisTick: {
          // 刻度相关
          show: true,
          alignWithLabel: true
        },
        axisLabel: {
          inside: false,
          color: '#666666',
          formatter: function (value)  //X轴的内容
          {
            let ret = ""; //拼接加\n返回的类目项
            let max = 14;  //每行显示的文字字数
            let val = value.length;  //X轴内容的文字字数
            let rowN = Math.ceil(val / max);  //需要换的行数
            if (rowN > 1)  //判断 如果字数大于2就换行
            {
              for (let i = 0; i < rowN; i++) {
                let temp = "";  //每次截取的字符串
                let start = i * max;  //开始截取的位置
                let end = start + max;  //结束截取的位置
                temp = value.substring(start, end) + "\n";
                ret += temp;  //最终的字符串
              }
              return ret;
            }
            else { return value }
          }
        }
      },
      color: [],
      dataZoom: {
        end: 100
      },
      grid: {
        left: 'left',
        bottom: 10,
        right: 0,
        top: 30
      },
      series: []
  },

})
const { systemAverageCost } = toRefs(state)
/** 监听 */
/** 生命周期 */
onMounted(() => {
  GetProReportBI()
})



/** 接口 */
const GetProReportBI = () => {
 
  systemAverageCost.value['series'] = []
  systemAverageCost.value['xAxis']['data'] = []
  // 接口结构
  res.data3 = [{
    {name:"213123",
    y:"123123"
  }]
  // 赋值
  const datas = {
        data: res.data3 ? res.data3.map(item => {
          return {
            value: item['y'],
            itemStyle: {
              color: "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")
            }
          }
        }) : [],
        type: 'bar',
        showBackground: true,
        label: {
          show: true,
          position: 'top',
          formatter: '{b}:{c} RMB'
        },
      }
   systemAverageCost.value['xAxis']['data'] = res.data3 ? res.data3.map(item => item['name']) : []
  systemAverageCost.value['series'].push(datas)
}
</script>
<style>
</style>