通用管理后台组件库-14-图表和富文本组件

图表组件和富文本组件

说明:图表组件使用Echarts做二次封装,富文本组件使用Vditor插件做二次封装。

1.实现效果

2.图表组件Charts.vue

xml 复制代码
<template>
  <div ref="chartRef" :style="chartStyle"></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts'
import type { ECharts, EChartsOption } from 'echarts'
import type { CSSProperties } from 'vue'

interface ChartsProps {
  option: EChartsOption
  height?: number | string
  width?: number | string
  autoresize?: boolean
}
const props = withDefaults(defineProps<ChartsProps>(), {
  autoresize: true
})

const attrsStyle = useAttrs()

const emits = defineEmits(['init'])

// shallowRef浅层响应式
const chartRef = shallowRef()

const chartInstance = shallowRef<ECharts>()

const chartStyle = computed(() => {
  // 获取父组件传递的样式
  const style = (attrsStyle.style || {}) as CSSProperties
  return {
    height: props.height
      ? typeof props.height === 'number'
        ? props.height + 'px'
        : props.height
      : '400px',
    width: props.width
      ? typeof props.width === 'number'
        ? props.width + 'px'
        : props.width
      : '100%',
    ...style
  }
})

function initChart() {
  if (chartRef.value) {
    // 初始化echarts实例
    chartInstance.value = echarts.init(chartRef.value)
    // 使用指定的配置项和数据显示图表
    chartInstance.value.setOption(props.option as EChartsOption)
    // 导出echarts实例
    emits('init', chartInstance.value)
  }
}
function resizeChart() {
  if (chartInstance.value) {
    chartInstance.value.resize()
  }
}
watch(
  () => props.option,
  () => {
    if (chartInstance.value) {
      chartInstance.value.setOption(props.option as EChartsOption)
    }
  },
  { deep: true }
)
const fn = useThrottleFn(resizeChart, 50)
onMounted(() => {
  initChart()
  // 监听窗口变化
  if (props.autoresize) {
    window.addEventListener('resize', fn)
  }
})
onUnmounted(() => {
  // 销毁实例
  chartInstance.value && chartInstance.value?.dispose()
  // 移除监听
  if (props.autoresize) {
    window.removeEventListener('resize', fn)
  }
})
</script>

<style scoped></style>

demo文件charts.vue