解决vue3+echarts关于无法获取dom宽度和高度的问题

news2024/9/30 3:31:36

解决vue3+echarts关于无法获取dom宽度和高度的问题

近期写vue3项目,很多地方都用到了echarts,刚开始写的时候,发现图一直出不来,报错/报警内容一般有两项:

  • Uncaught (in promise) Error: Initialize failed: invalid dom.
  • vue3 [ECharts] Can’t get DOM width or height.

分别解释一下这俩报错

第一个报错是在初始化echarts的时候,没有找到对应的dom元素,所以需要在dom元素渲染完成后再初始化echarts图

第二个报错是说不能获取到echarts对应dom的宽或高,这个问题一般出现在设置dom节点的宽和高时,用了百分比形式,ECharts的宽高默认是以像素为单位的,并不能直接使用百分比来设置

经过多次尝试,总算解决这个问题了,记录一下解决方案

先上代码:

<template>
  <div class="right">
    <div class="top">
      <div class="top-left" ref="topLeft"></div>
      <div class="top-right" ref="topRight"></div>
    </div>
    <div class="middle" ref="middle"></div>
    <div class="bottom">
      <div class="bottom-left" ref="bottomLeft"></div>
      <div class="bottom-right" ref="bottomRight"></div>
    </div>
  </div>
</template>

<script setup>
import * as echarts from "echarts";
import { ref, onMounted } from 'vue'
import { driverAgeLT, driverAgeRT, driverAgeMiddle, driverAgeBL, driverAgeBR } from './graphOptions.js'

const topLeft = ref(null)
const LTOptions = driverAgeLT()
const drawLTchart = () => {
  const topLeftChart = echarts.init(topLeft.value)
  topLeftChart.setOption(LTOptions)
  topLeftChart.resize()
  window.addEventListener('resize', () => {
    topLeftChart.resize()
  })
}

const topRight = ref(null)
const RTOptions = driverAgeRT()
const drawRTchart = () => {
  const topRightChart = echarts.init(topRight.value)
  topRightChart.setOption(RTOptions)
  topRightChart.resize()
  window.addEventListener('resize', () => {
    topRightChart.resize()
  })
}

const middle = ref(null)
const middleOptions = driverAgeMiddle()
const drawMiddleChart = () => {
  const midddleChart = echarts.init(middle.value)
  midddleChart.setOption(middleOptions)
  midddleChart.resize()
  window.addEventListener('resize', () => {
    midddleChart.resize()
  })
}

const bottomLeft = ref(null)
const BLOptions = driverAgeBL()
const drawBLchart = () => {
  const bottomLeftChart = echarts.init(bottomLeft.value)
  bottomLeftChart.setOption(BLOptions)
  bottomLeftChart.resize()
  window.addEventListener('resize', () => {
    bottomLeftChart.resize()
  })
}

const bottomRight = ref(null)
const BROptions = driverAgeBR()
const drawBRchart = () => {
  const bottomRightChart = echarts.init(bottomRight.value)
  bottomRightChart.setOption(BROptions)
  bottomRightChart.resize()
  window.addEventListener('resize', () => {
    bottomRightChart.resize()
  })
}

onMounted(() => {
  setTimeout(() => {
    drawLTchart()
    drawRTchart()
    drawMiddleChart()
    drawBLchart()
    drawBRchart()
  }, 200)
})
</script>

<style lang="scss" scoped>
.right {
  width: 49%;
  margin-left: 10px;
  height: 99%;
  display: flex;
  flex-direction: column;
  padding: 10px;
  box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;

  .top {
    height: 33%;
    display: flex;
    box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset;

    .top-left {
      width: 50%;
      padding: 5px;
      height: 100%;
      border-right: 1px dashed #ccc;
    }

    .top-right {
      width: 50%;
      padding: 5px;
      height: 100%;
    }
  }

  .middle {
    margin-top: 5px;
    height: 33%;
    padding: 5px;
    width: 100%;
    box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset;
  }

  .bottom {
    height: 33%;
    margin-top: 5px;
    display: flex;
    box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset;

    .bottom-left {
      width: 50%;
      padding: 5px;
      height: 100%;
      border-right: 1px dashed #ccc;
    }

    .bottom-right {
      width: 50%;
      padding: 5px;
      height: 100%;
    }
  }
}
</style>

效果
在这里插入图片描述

代码我只放了图的那一部分,代码的作用是在页面的右侧画5张图,从我写的样式可以看出,所有画图的dom我都用了百分比,这样有个好处,不管什么屏幕,都可以比较好的显示,但是echarts并不支持百分比的宽高,所以狂报警

接下来解释一下代码:

  • import { driverAgeLT, driverAgeRT, driverAgeMiddle, driverAgeBL, driverAgeBR } from './graphOptions.js'这行代码是我把5张图的options都放到一个js文件里了,也是组件式开发的一个体现,这个文件我就不放上了,想怎么画图自己去设置

  • 下面这几行代码是关键,我直接通过注释的形式来解释

    const topLeft = ref(null)  // 获取dom
    const LTOptions = driverAgeLT()  // 获取对应的options
    const drawLTchart = () => {  // 画图函数,为啥要写成函数,因为需要在页面加载完成后调用,要放在生命周期函数中
      const topLeftChart = echarts.init(topLeft.value)  // 初始化echarts图,注意,这里的topLeft是响应式的dom,必须要加value,这里我经常忘记
      topLeftChart.setOption(LTOptions)  // 设置option
      topLeftChart.resize()  // 这里也比较关键,在option后,最好是重绘一下图,可以解决百分比宽高的问题,也就是解决第2个问题
      window.addEventListener('resize', () => {  // 窗口大小变化后,重绘图
        topLeftChart.resize()
      })
    }
    
    onMounted(() => {  // vue3的生命周期函数,在页面加载完成后,再画图,其实就是解决第1个问题
      setTimeout(() => {  // 这里为啥要用定时器在0.2s后再画图呢,其实我也不能确定是不是这个问题,但是这么写后,确实解决了问题,
        drawLTchart()     // 续上:页面加载完成后,dom不一定渲染完成了,所以这里的定时器是为了让dom渲染后再绘图
        drawRTchart()
        drawMiddleChart()
        drawBLchart()
        drawBRchart()
      }, 200)
    })
    

这样就解决了上面两个问题了

不过还有个问题得说一下,很明显,我用了elementplus作为UI框架,我特别喜欢el-card这个组件,所以很多时候我都用它来做布局,但是我在用的时候,发现我很难掌握它的布局规律,尤其是在结合echarts画图的时候,各种dom相关的问题层出不穷,所以我不得不放弃使用el-card,二是自己用div来做布局。其实也就是个盒子阴影的问题,不会设计?当然不用自己造轮子,放一下各种花式的边框阴影~

完,希望所有bug退散~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/837243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓证书生成教程

1.下载安装JDK文件&#xff08;如已安装请跳过&#xff09; 根据电脑系统版本下载JDK版本文件 下载地址&#xff1a;[https://www.oracle.com/java/technologies/downloads/](https://www.oracle.com/java/technologies/downloads/) 如果电脑上安装过JDK文件可以跳过2.生成密钥…

electron+vue3全家桶+vite项目搭建【25】使用electron-updater自动更新应用

文章目录 引入实现效果实现步骤引入依赖配置electron-buidler文件封装版本升级工具类主进程调用版本更新校验渲染进程封装方法调用 测试版本更新 引入 demo项目地址 electron-updater官网 我们不可能每次发布新的版本都让用户去手动下载安装最新的包&#xff0c;而是应用可以…

不懂这些专业名词,你很难成为有水平的项目经理——数据分析篇

大家好&#xff0c;我是老原。 前段时间我们项目组招了个新人小林&#xff0c;让他去和产品经理对下产品上线情况&#xff0c;等到下班也没等来反馈。 第二天在茶水间遇到了产品经理就问了一嘴&#xff0c;才知道已经对接到位了。 一问小林才知道&#xff0c;他完全不知道产…

跨境电商的广告推广怎么做?7个方法

在跨境电商竞争日趋激烈的市场环境下&#xff0c;跨境电商店铺引流成了制胜关键点。这里给大家分享一套引流推广的方法。 一、搜索引擎营销推广 搜索引擎有两个最大的优点是更灵活、更准确。搜索引擎营销的目标定位更精确&#xff0c;且不受时间和地理位置上的限制&#xff0…

Live800:未来的在线客服系统有哪些挑战?

科技的不断发展和人工智能的逐步成熟&#xff0c;让在线客服系统已成为许多企业提供优质服务的重要手段。在线客服系统显然并不是一成不变的&#xff0c;未来的在线客服系统必将与时俱进不断升级优化。那么&#xff0c;你知道在未来在线客服系统将面临哪些挑战呢&#xff1f; 这…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(29)-Fiddler如何抓取Android7.0以上的Https包-终篇

1.简介 上一篇宏哥介绍的Xposed是一款可以在不修改APK的情况下影响程序运行的框架。可以编写并加载自己编写的插件app&#xff0c;实现对目标apk的注入、拦截等。一般研究移动安全的都会使用Xposed。 Xposed框架已停止更新&#xff0c;它支持android 6.0-8.1&#xff0c;但它…

Maven依赖爆红的解决思路

说明&#xff1a;本文介绍Maven依赖爆红&#xff0c;排查错误的几种思路&#xff1b; 思路一&#xff1a;删除本地仓库.lastupdate文件&#xff1b; 找到本地maven仓库&#xff0c;全局搜索.lastupdate文件&#xff0c;把搜索出来的文件全部删除。.lastupdate后缀名的文件&am…

音频转文字软件哪个好用?这些软件你不容错过

在一个繁忙的办公室里&#xff0c;小明正在与他的同事小李聊天。突然&#xff0c;小明兴奋地拍了拍桌子&#xff0c;眉开眼笑地对小李说道&#xff1a;你知道吗&#xff1f;我近期发现了一个实用的音频转文字工具&#xff01;它可以帮助我们将音频转换成文字。 小李&#xff1…

UML-活动图

目录 一.活动图概述: 1.活动图的作用&#xff1a; 2.以下场合不使用活动图&#xff1a; 3.活动图的基本要素&#xff1a; 4.活动图的图符 4.1起始状态 4.2终止状态 4.3状态迁移 4.4决策点 4.5同步条:表示活动之间的不同 5.活动图: 二.泳道&#xff1a; 1.泳道图&a…

VS2017中Qt工程报错:无法解析的外部符号 __imp_CommandLineToArgvW,该符号在函数 WinMain 中被引用

工程报错:无法解析的外部符号 __imp_CommandLineToArgvW&#xff0c;该符号在函数 WinMain 中被引用 解决方法&#xff1a; 在输入的附加依赖项中增加 shell32.lib

信驰达RF-BM-2340B1开发套件加速CC2340R5产品化

TI第四代低功耗蓝牙SoC-CC2340一发布就在物联网通信模组厂商、方案商和成品厂商中引起了广泛关注。随着该芯片的量产&#xff0c;使用芯片或模块进行开发调试成为开发者面临的首要问题。作为无线通信模块老牌厂商&#xff0c;深圳市信驰达科技有限公司第一时间基于CC2340R5推出…

web测试方法总结

1. 登录测试 1.1 输入正确的用户名和正确的密码&#xff0c;看输出结果是否正确 1.2 输入正确的用户名和错误的密码&#xff0c;并给出合理的提示 1.3 输入错误的用户名和正确的密码&#xff0c;并给出合理的提示 1.4 输入错误的用户名和错误的密码&#xff0c;并给出合理的…

接口测试之文件上传

在日常工作中&#xff0c;经常有上传文件功能的测试场景&#xff0c;因此&#xff0c;本文介绍两种主流编写上传文件接口测试脚本的方法。 首先&#xff0c;要知道文件上传的一般原理&#xff1a;客户端根据文件路径读取文件内容&#xff0c;将文件内容转换成二进制文件流的格式…

安达发|模具制造业对APS软件需求大幅增长

近年来&#xff0c;中国模具工业以每年15%左右的增速速度快速发展。然而&#xff0c;对于大型、精密、复杂及长寿命模具的需求增长将远超过每年15%的增幅。为应对这一挑战&#xff0c;模具制造业对APS软件的需求大幅度增长&#xff0c;助力行业提速发展。 据统计&#xff0c;中…

16.M端事件和JS插件

16.1移动端 移动端也有自己独特的地方 ●触屏事件touch (也称触摸事件)&#xff0c;Android 和I0S都有。 ●touch对象代表一个触摸点。触摸点可能是一根手指&#xff0c;也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。 ●常见的触屏事件如下: …

获取SQL语句表名,判断DDL类型

1.在maven中引入jsqlparser依赖 <!--sql语句解析--><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.4</version></dependency>2.解析SQL语句具体代码 此代码解析…

如何消除“信息孤岛”对业务增长的威胁?

根据CMSWire的数据&#xff0c;员工平均每天要花36%的时间来查找和整合信息。但44%的情况下&#xff0c;他们找不到信息。这种时间和精力的浪费就是信息孤岛造成的。 什么是信息孤岛&#xff1f; 当部门存储数据并限制其他人访问数据时&#xff0c;就会出现信息孤岛&#xff…

动态代理类之万能模板

ProxyInvocationHandler package com.heerlin.demo03;import com.heerlin.demo02.Rent;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;//用这个类&#xff0c;自动生成代理类 public class ProxyInvocationH…

LeetCode每日一题Day5——21. 合并两个有序链表

✨博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;算法修炼之练气篇&#xff08;C\C版&#xff09; &#x1f353;专栏&#xff1a;算法修炼之筑基篇&#xff08;C\C版&#xff09; &#x1f433;专栏&#xff1a;算法修炼之练气篇&#xff08;Python版&#xff09; …

力扣 1049. 最后一块石头的重量 II

题目来源&#xff1a;https://leetcode.cn/problems/last-stone-weight-ii/description/ C题解&#xff08;思路来源代码随想录&#xff09;&#xff1a;本题其实就是尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;这样就化解成01背包问题了。 …