首页 > 其他分享 >vue2 自定义empty指令

vue2 自定义empty指令

时间:2024-09-29 21:19:38浏览次数:11  
标签:el const observer 自定义 myChart height width vue2 empty

主要思路

  1. 定义一个echarts图标,数据为空,image采用base64编码
  2. 图标宽高根据父宽高自适应
  3. 渲染echarts函数,切换清除图例
  4. 定义暂无数据指令

定义option

/**
 * 暂无数据
 * @param {number} width
 * @param {number} height
 * @returns option
 */
function emptyChartOptionFn(width = 150, height = 120) {
  return {
    title: {
      text: `{a|}\n{b|暂无数据}`,
      x: 'center',
      y: 'center',
      itemGap: 0,
      textStyle: {
        rich: {
          a: {
            height,
            width,
            backgroundColor: {
              image:
                'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTU1IiBoZWlnaHQ9IjEyMCIgdmlld0JveD0iMCAwIDE1NSAxMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIG9wYWNpdHk9IjAuNiI+CjxyZWN0IHg9IjgyLjU0MyIgeT0iMTIiIHdpZHRoPSI3MCIgaGVpZ2h0PSI5MCIgcng9IjYiIHRyYW5zZm9ybT0icm90YXRlKDYuMDg2NjYgODIuNTQzIDEyKSIgZmlsbD0iI0Y1RjZGQSIgc3Ryb2tlPSIjOEY5QUIyIi8+CjxyZWN0IG9wYWNpdHk9IjAuMiIgeD0iOTMuMzQ5IiB5PSIzMy4yNjU2IiB3aWR0aD0iMTMiIGhlaWdodD0iMiIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKDYuMDg2NjYgOTMuMzQ5IDMzLjI2NTYpIiBmaWxsPSIjOEY5QUIyIi8+CjxyZWN0IHg9IjExMC4yNTMiIHk9IjM1LjA2ODQiIHdpZHRoPSIyNyIgaGVpZ2h0PSIyIiByeD0iMSIgdHJhbnNmb3JtPSJyb3RhdGUoNi4wODY2NiAxMTAuMjUzIDM1LjA2ODQpIiBmaWxsPSIjOEY5QUIyIi8+CjxyZWN0IHg9IjkxLjg2NDYiIHk9IjQ3LjE4NjUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIyIiByeD0iMSIgdHJhbnNmb3JtPSJyb3RhdGUoNi4wODY2NiA5MS44NjQ2IDQ3LjE4NjUpIiBmaWxsPSIjOEY5QUIyIi8+CjxyZWN0IG9wYWNpdHk9IjAuMiIgeD0iMTI3LjY2MiIgeT0iNTEuMDAzOSIgd2lkdGg9IjgiIGhlaWdodD0iMiIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKDYuMDg2NjYgMTI3LjY2MiA1MS4wMDM5KSIgZmlsbD0iIzhGOUFCMiIvPgo8cmVjdCBvcGFjaXR5PSIwLjIiIHg9Ijg4Ljg5NTYiIHk9Ijc1LjAyODgiIHdpZHRoPSIzMi42ODg0IiBoZWlnaHQ9IjIiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSg2LjA4NjY2IDg4Ljg5NTYgNzUuMDI4OCkiIGZpbGw9IiM4RjlBQjIiLz4KPHJlY3QgeD0iOTAuMzgwMSIgeT0iNjEuMTA3OSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSg2LjA4NjY2IDkwLjM4MDEgNjEuMTA3OSkiIGZpbGw9IiM4RjlBQjIiLz4KPHJlY3Qgb3BhY2l0eT0iMC4yIiB4PSIxMTQuMjQ1IiB5PSI2My42NTI4IiB3aWR0aD0iMjAiIGhlaWdodD0iMiIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKDYuMDg2NjYgMTE0LjI0NSA2My42NTI4KSIgZmlsbD0iIzhGOUFCMiIvPgo8L2c+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2RfMjA0MF82NjU5OCkiPgo8cmVjdCB4PSIxNy4zMzQ0IiB5PSIxMDIuNzEiIHdpZHRoPSI3MCIgaGVpZ2h0PSIxMDAiIHJ4PSI2IiB0cmFuc2Zvcm09InJvdGF0ZSgtOTcuNjYzMSAxNy4zMzQ0IDEwMi43MSkiIGZpbGw9IiNGNUY2RkEiIHN0cm9rZT0iIzhGOUFCMiIvPgo8Y2lyY2xlIG9wYWNpdHk9IjAuMiIgY3g9IjMzLjU5NjciIGN5PSI0OC40MjQzIiByPSI4IiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSAzMy41OTY3IDQ4LjQyNDMpIiBzdHJva2U9IiM3QTg1OTkiIHN0cm9rZS13aWR0aD0iMS40Ii8+CjxwYXRoIGQ9Ik0zNC42NjM0IDU2LjM1MjhDMzYuMzYyMSA1Ni4xMjQzIDM3Ljk0MjQgNTUuMzU2MiAzOS4xNzE3IDU0LjE2MThDNDAuNDAwOSA1Mi45Njc0IDQxLjIxNCA1MS40MDk3IDQxLjQ5MTMgNDkuNzE4NEM0MS43Njg1IDQ4LjAyNyA0MS40OTUzIDQ2LjI5MTMgNDAuNzExNyA0NC43NjY5QzM5LjkyODEgNDMuMjQyNSAzOC42NzU3IDQyLjAxMDEgMzcuMTM4OSA0MS4yNTEyQzM1LjYwMjEgNDAuNDkyMyAzMy44NjIyIDQwLjI0NyAzMi4xNzU1IDQwLjU1MTVDMzAuNDg4OCA0MC44NTYgMjguOTQ0NSA0MS42OTQxIDI3Ljc3IDQyLjk0MjRDMjYuNTk1NiA0NC4xOTA4IDI1Ljg1MzEgNDUuNzgzMyAyNS42NTE5IDQ3LjQ4NTRDMjUuNDUwOCA0OS4xODc1IDI1LjgwMTYgNTAuOTA5MiAyNi42NTI3IDUyLjM5NjkiIHN0cm9rZT0iIzhGOUFCMiIgc3Ryb2tlLXdpZHRoPSIyIi8+CjxjaXJjbGUgb3BhY2l0eT0iMC4yIiBjeD0iMzYuMjYzNyIgY3k9IjY4LjI0NTYiIHI9IjUiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDM2LjI2MzcgNjguMjQ1NikiIHN0cm9rZT0iIzdBODU5OSIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KPHBhdGggZD0iTTM2LjkzMDQgNzMuMjAxQzM3LjkxMDUgNzMuMDY5MSAzOC44Mjk1IDcyLjY0OTYgMzkuNTcxMSA3MS45OTU0QzQwLjMxMjcgNzEuMzQxMyA0MC44NDM4IDcwLjQ4MTkgNDEuMDk3IDY5LjUyNkM0MS4zNTAyIDY4LjU3IDQxLjMxNDMgNjcuNTYwNSA0MC45OTM3IDY2LjYyNUM0MC42NzMyIDY1LjY4OTUgNDAuMDgyNSA2NC44NyAzOS4yOTYyIDY0LjI3MDJDMzguNTA5OSA2My42NzA1IDM3LjU2MzUgNjMuMzE3MyAzNi41NzY1IDYzLjI1NTRDMzUuNTg5NSA2My4xOTM2IDM0LjYwNjQgNjMuNDI1OCAzMy43NTE0IDYzLjkyMjZDMzIuODk2NCA2NC40MTk1IDMyLjIwNzkgNjUuMTU4OCAzMS43NzMgNjYuMDQ3QzMxLjMzODIgNjYuOTM1MSAzMS4xNzY1IDY3LjkzMjMgMzEuMzA4MyA2OC45MTI0IiBzdHJva2U9IiM4RjlBQjIiIHN0cm9rZS13aWR0aD0iMiIvPgo8Y2lyY2xlIG9wYWNpdHk9IjAuMiIgY3g9IjM4LjUzMDUiIGN5PSI4NS4wOTM4IiByPSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSAzOC41MzA1IDg1LjA5MzgpIiBzdHJva2U9IiM3QTg1OTkiIHN0cm9rZS13aWR0aD0iMS40Ii8+CjxwYXRoIGQ9Ik00My40ODU5IDg0LjQyN0M0My4zODkgODMuNzA3MSA0My4xMzY0IDgzLjAxNjkgNDIuNzQ1NyA4Mi40MDQ1QzQyLjM1NSA4MS43OTIxIDQxLjgzNTUgODEuMjcyMSA0MS4yMjM0IDgwLjg4MDlDNDAuNjExMyA4MC40ODk3IDM5LjkyMTQgODAuMjM2NSAzOS4yMDE1IDgwLjEzOUMzOC40ODE2IDgwLjA0MTUgMzcuNzQ5MiA4MC4xMDIxIDM3LjA1NTEgODAuMzE2NEMzNi4zNjEgODAuNTMwOCAzNS43MjE5IDgwLjg5MzggMzUuMTgyNCA4MS4zODAzQzM0LjY0MjkgODEuODY2NyAzNC4yMTU4IDgyLjQ2NDkgMzMuOTMxIDgzLjEzMzJDMzMuNjQ2MSA4My44MDE0IDMzLjUxMDMgODQuNTIzNyAzMy41MzMgODUuMjQ5OEMzMy41NTU2IDg1Ljk3NTkgMzMuNzM2MiA4Ni42ODgzIDM0LjA2MjIgODcuMzM3NSIgc3Ryb2tlPSIjOEY5QUIyIiBzdHJva2Utd2lkdGg9IjIiLz4KPHJlY3Qgb3BhY2l0eT0iMC4yIiB4PSI1Ny4wMDA0IiB5PSI1Ny4zODM4IiB3aWR0aD0iMzgiIGhlaWdodD0iMiIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDU3LjAwMDQgNTcuMzgzOCkiIGZpbGw9IiM3QTg1OTkiLz4KPHJlY3Qgb3BhY2l0eT0iMC4yIiB4PSI2MS4wMDA5IiB5PSI4Ny4xMTU3IiB3aWR0aD0iMzgiIGhlaWdodD0iMiIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDYxLjAwMDkgODcuMTE1NykiIGZpbGw9IiM3QTg1OTkiLz4KPHJlY3Qgb3BhY2l0eT0iMC4yIiB4PSI1Ny4wMzk5IiB5PSIzNS4xODAyIiB3aWR0aD0iMiIgaGVpZ2h0PSIyMSIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDU3LjAzOTkgMzUuMTgwMikiIGZpbGw9IiM3QTg1OTkiLz4KPHJlY3Qgb3BhY2l0eT0iMC4yIiB4PSI1OC4wNjcxIiB5PSI2NS4zMTIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI0IiByeD0iMSIgdHJhbnNmb3JtPSJyb3RhdGUoLTcuNjYzMDkgNTguMDY3MSA2NS4zMTIpIiBmaWxsPSIjN0E4NTk5Ii8+CjxyZWN0IG9wYWNpdHk9IjAuMiIgeD0iNjYuOTUwNyIgeT0iMzMuODQ2NyIgd2lkdGg9IjIiIGhlaWdodD0iMjEiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSA2Ni45NTA3IDMzLjg0NjcpIiBmaWxsPSIjN0E4NTk5Ii8+CjxyZWN0IG9wYWNpdHk9IjAuMiIgeD0iNzYuODYxMyIgeT0iMzIuNTEzMiIgd2lkdGg9IjIiIGhlaWdodD0iMjEiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSA3Ni44NjEzIDMyLjUxMzIpIiBmaWxsPSIjN0E4NTk5Ii8+CjxyZWN0IG9wYWNpdHk9IjAuMiIgeD0iODYuNzcyMSIgeT0iMzEuMTc5NyIgd2lkdGg9IjIiIGhlaWdodD0iMjEiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSA4Ni43NzIxIDMxLjE3OTcpIiBmaWxsPSIjN0E4NTk5Ii8+CjxyZWN0IHg9IjU4Ljc3MzQiIHk9IjQ4LjA2NCIgd2lkdGg9IjIiIGhlaWdodD0iOCIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDU4Ljc3MzQgNDguMDY0KSIgZmlsbD0iIzhGOUFCMiIvPgo8cmVjdCB4PSI2Ny40ODQiIHk9IjM3LjgxMSIgd2lkdGg9IjIiIGhlaWdodD0iMTciIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSA2Ny40ODQgMzcuODExKSIgZmlsbD0iIzhGOUFCMiIvPgo8cmVjdCB4PSI3OC4xOTQ4IiB5PSI0Mi40MjM4IiB3aWR0aD0iMiIgaGVpZ2h0PSIxMSIgcng9IjEiIHRyYW5zZm9ybT0icm90YXRlKC03LjY2MzA5IDc4LjE5NDggNDIuNDIzOCkiIGZpbGw9IiM4RjlBQjIiLz4KPHJlY3QgeD0iODYuOTA1NCIgeT0iMzIuMTcwOSIgd2lkdGg9IjIiIGhlaWdodD0iMjAiIHJ4PSIxIiB0cmFuc2Zvcm09InJvdGF0ZSgtNy42NjMwOSA4Ni45MDU0IDMyLjE3MDkpIiBmaWxsPSIjOEY5QUIyIi8+CjxwYXRoIGQ9Ik02NC41NjUgODMuNjA4OUw3MS4xMzk3IDczLjQzMkw4NS41MzQ4IDgwLjc4NzVMOTIuMzQ3NCA3Ni4wNjk0TDk1LjAwMzQgNjIuMzYwMyIgc3Ryb2tlPSIjOEY5QUIyIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2RfMjA0MF82NjU5OCIgeD0iMC4yNDU3MjgiIHk9IjEyLjI0NjEiIHdpZHRoPSIxMjcuOTUiIGhlaWdodD0iMTAyLjIxOCIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVDb2xvck1hdHJpeCBpbj0iU291cmNlQWxwaGEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIgcmVzdWx0PSJoYXJkQWxwaGEiLz4KPGZlT2Zmc2V0IGR4PSIyIiBkeT0iMiIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI1Ii8+CjxmZUNvbXBvc2l0ZSBpbjI9ImhhcmRBbHBoYSIgb3BlcmF0b3I9Im91dCIvPgo8ZmVDb2xvck1hdHJpeCB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4xNSAwIi8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0iZWZmZWN0MV9kcm9wU2hhZG93XzIwNDBfNjY1OTgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJlZmZlY3QxX2Ryb3BTaGFkb3dfMjA0MF82NjU5OCIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8L3N2Zz4K',
            },
          },
          b: {
            verticalAlign: 'top',
            fontSize: 12,
            lineHeight: 18,
            color: '#686E7C',
          },
        },
      },
      subtextStyle: {
        fontSize: 12,
      },
    },
  }
}

自适配宽高

const getEmptyWH = el => {
  let width = 150
  let height = 120

  // 宽度不够
  if (el.clientWidth < 150) {
    let radio = 120 / 150
    width = el.clientWidth
    height = width * radio
  }
  // 高度不够
  if (el.clientHeight < 120) {
    let radio = 150 / 120
    height = el.clientHeight - 20
    width = height * radio
  }
  return {
    width,
    height,
  }
}

渲染echarts图标至el

const emptyChartFn = el => {
  //初始化echart
  let myChart = Vue.prototype.$echarts.init(el, 'light', {
    height: 'auto',
    width: 'auto',
  })

  const { width, height } = getEmptyWH(el)
  myChart.setOption(optionFn(width, height))

  // myChart绑定到el上,方便后续调用
  el.myChart = myChart
  el.showLoading = myChart.showLoading
  el.hideLoading = myChart.hideLoading
  // 监听屏幕变化
  el.debounceResize = debounce(() => {
    const { width, height } = getEmptyWH(el)
    // 清空当前实例
    el.myChart.clear()
    // 重新绘制
    el.myChart.setOption(optionFn(width, height))
    // 必须加上resize,否则不起作用
    el.myChart.resize({
      animation: {
        duration: 200,
      },
    })
  }, 500)
  // window.addEventListener('resize', el.debounceResize)
  const observer = new ResizeObserver(el.debounceResize)
  observer.observe(el)
  el._observer = observer
}

定义暂无数据指令

// 暂无数据指令
const emptyChart = {
  inserted(el, binding, vnode) {
    const isEmpty = binding.value
    if (!isEmpty) {
      return
    }

    Vue.nextTick(() => {
      emptyChartFn(el)
    })
  },
  update(el, binding, vnode) {
    const isEmpty = binding.value
    if (isEmpty) {
      let myChart = el?.myChart
      if (!myChart) {
        emptyChartFn(el)
      } else {
        myChart.clear()
        emptyChartFn(el)
      }
    }
  },
  //指令卸载的时候去除window事件监听
  unbind(el, binding, vnode) {
    // window.removeEventListener('resize', el.debounceResize)
    const observer = el._observer
    if (observer) {
      observer.unobserve(el)
      delete el._observer
    }
  },
}

注册指令

Vue.directive('emptyChart', emptyChart)

使用

<div v-empty-chart="isEmpty" class="h-full pt-6"></div>

效果

在这里插入图片描述

标签:el,const,observer,自定义,myChart,height,width,vue2,empty
From: https://blog.csdn.net/weixin_41886421/article/details/142643951

相关文章

  • java-快速将普通main类变为javafx类,并加载自定义fxml
    java-快速将普通main类变为javafx类,并加载自定义fxml前提步骤1.普通类继承Application2.实现main方法3.写一个controller4.写一个fxml文件5.写start方法加载fxml6.具体代码7.运行即可前提使用自带javafx的jdk,这里使用的是jdk1.834,当然你可以使用其他的可行......
  • 开源模型应用落地-LangChain实用小技巧-文档分割器-自定义文档分割器(十三)
    一、前言  在LangChain框架中,文档分割器是一种将大段文本拆分成较小块或片段的算法或方法。其目标是创建可单独处理的可管理的片段,这在处理大型文档或数据集时通常是必要的。  而自定义文档分割器可以根据特定的需求和数据类型进行定制和配置,以便更好地适应应用程......
  • 【Ambari自定义组件集成】Ambari汉化,源码级修改手把手教程
    传统方式注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0注意:此方法适合ambari-2.8.0Step1、找到代码位置:ambari-project\ambari-web\app\messages.js逐一替换Step2、下载我提供的汉化好的:message.jshttps://gitee.com/tt-bigdata/ambari-en-cn/blob/ma......
  • spring 常见注解记录+ 使用自定义注解与aop 记录接口请求参数
    注解定义:importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;importorg.springframework.core.annotation.Alias......
  • Springboot自定义Prometheus采集指标
    添加依赖<!--增加Prometheus依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.micrometer&l......
  • Python基于自定义方法的排序
    Python基于自定义方法的排序在Python中,排序是一个常见的任务,它可以帮助我们根据特定的规则对数据结构(如列表)中的元素进行排序。Python的内置排序方法,如列表的sort()函数和内置函数sorted(),提供了非常灵活的排序机制,特别是通过key参数,我们可以指定一个自定义的函数来决定排序的顺......
  • 基于qwen2.5 手把手实战 自定义数据集 微调(llama-factory)
    基于qwen2.5手把手实战自定义数据集微调(llama-factory)准备工作1.数据集准备(例:民法典.txt)2.服务器准备(阿里云DSW白嫖)3.环境配置pip升级模型下载微调助手4.数据集处理脚本文件4.1文本分割(bert-base-chinese)4.2数据集生成4.3.1数据集转换(只有一个数据集)alpaca格式......
  • PbootCMS自定义前台404错误页面
    以下是一个简单的404错误页面示例代码:<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>......
  • [米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-26PL 自定义 AXI-Lite-频率计
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA实验平台:米联客-MLK-H3-CZ08-7100开发板板卡获取平台:https://milianke.tmall.com/登录“米联客”FPGA社区http://www.uisrc.com视频课程、答疑解惑!目录1概述2系统框图3等精度......
  • [米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-23PL 自定义 AXI-Lite 协议 IP
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA实验平台:米联客-MLK-H3-CZ08-7100开发板板卡获取平台:https://milianke.tmall.com/登录“米联客”FPGA社区http://www.uisrc.com视频课程、答疑解惑!目录1概述2系统框图3AXI总线......