Vue3 + Echarts堆叠折线图的tooltip不显示问题

问题介绍

使用Echarts在Vue3+Vite项目中绘制堆叠折线图的的时候,tooltip总是不显示,经过很长时间的排查和修改,最后发现是在使用上有错误导致的。

错误图片展示

问题原因

由于Vue3底层使用proxy代理创建示例,使用其创建出来的实例与Echarts真正使用的的实例存在兼容性问题,所以Echarts无法从中获取内部变量,所以在使用Echarts实例的时候,不要使用ref或reactive等响应式方法创建Echarts对象,应该使用shallowReactive、shallowRef或者普通变量。

导致问题代码

const chartInstance3 = ref(null); //定义店铺入驻明细图表实例化
const chartContainer3 = ref();

shallowReactive、shallowRef与reactive、ref的区别

API介绍
reactive
  • reactive用于将一个对象变成响应式的。它会深度遍历对象的属性,使其内部的所有属性也变为响应式的。因此,当你修改任何层级的属性时,都会触发依赖这些属性的组件的更新。
  • 它适用于那些结构复杂并且需要整个对象及其所有属性都是响应式的情况。
shallowReactive
  • shallowReactive同样用于将对象变成响应式的,但是它只会使对象的顶层属性响应式,而不会深入到对象的嵌套属性中。这意味着如果你有一个嵌套的对象,其内部的属性更改将不会触发响应性更新。
  • 这个API对于处理大型数据结构特别有用,因为它避免了深度遍历带来的性能开销。
ref
  • ref用于创建一个响应式的引用类型,它包装了一个基本类型值或一个复杂的类型。ref的值可以通过.value属性访问和修改。
  • ref可以用于任何数据类型,但是当它包装复杂类型(如对象或数组)时,整个ref对象本身仍然是响应式的,内部的复杂类型也会被转化为响应式类型(通过reactive)。
  • ref主要用于状态管理,尤其是那些需要在组件之间共享的状态。
shallowRef
  • shallowRefref相似,但它不会将内部的复杂类型转化为响应式类型。这意味着如果shallowRef的值是一个对象,那么这个对象的内部属性更改将不会触发响应性更新。
  • 这种行为在处理大型数据结构或外部库提供的对象时非常有用,因为它们可能不希望被Vue的响应系统所影响。

总结:

  • reactiveref都提供深度响应性,但ref还提供了一层额外的封装。
  • shallowReactiveshallowRef仅提供一层响应性,这对于性能敏感的应用或不需要深度响应性的数据结构很有用。

修改后的实现效果

修改后的代码

const chartInstance3 = shallowRef(null); //定义店铺入驻明细图表实例化
const chartContainer3 = shallowRef();

附完整代码

<template><divref="chartContainer3"style="width: 100%; height: 400px; margin-top: 20px"></div>
</template><script setup>
import * as echarts from "echarts";
import { onMounted, onUnmounted, ref, shallowRef } from "vue";
import request from "@/utils/request";
import api from "@/api";
import formatTime from "@/utils/formatTime";
const chartInstance3 = shallowRef(null); //定义店铺入驻明细图表实例化
const chartContainer3 = shallowRef();const ServiceCategoryList = ref([]); //店铺类别列表
// 获取所有店铺类别
const getShopCategory = async () => {const res = await request.get(api.getShopCategory);res.data.forEach((item) => {ServiceCategoryList.value.push({name: item.name,type: "line", //图标的类型,line:折线图// stack: "total",shopType: item.type,smooth: "true",data: [],});});
};
const shopList = ref([]); //入驻店铺列表
const startTime = ref(""); //入住店铺最早的创建时间
const endTime = new Date(); //当前时间
const dateArray = ref([]); //日期数组
// 创建时间列表
const createTimeList = (start, end) => {while (start <= end) {dateArray.value.push(start.toISOString().substring(0, 10)); // 只保留YYYY-MM-DD格式start.setDate(start.getDate() + 1); // 增加一天}
};
// 获取入驻平台的所有店铺
const getShopList = async () => {await request.get(api.shopList).then((res) => {res.data.forEach((item) => {item.createTime = formatTime(item.createTime).nohour;item.createTimeObj = new Date(item.createTime);shopList.value.push({shopName: item.shopName,createTime: item.createTime,shopType: item.shopType,});});// 使用sort方法对shopList按创建时间排序,并找出最早入驻的时间res.data.sort((a, b) => a.createTimeObj - b.createTimeObj);startTime.value = new Date(res.data[0].createTime);createTimeList(startTime.value, endTime); //生成时间列表// 将所有的店铺按照店铺类别进行分组const shopsGroupedByTypeAndTime = res.data.reduce((groups, shop) => {const shopType = shop.shopType;const shopTime = shop.createTime;// 如果还没有对应店铺类型的分组,则创建它if (!groups[shopType]) {groups[shopType] = {};}// 如果还没有对应时间的分组,则创建它if (!groups[shopType][shopTime]) {groups[shopType][shopTime] = 0;}// 将对应时间和类型的计数增加1groups[shopType][shopTime]++;return groups;}, {});ServiceCategoryList.value.forEach((item) => {if (shopsGroupedByTypeAndTime[item.shopType]) {item.data = shopsGroupedByTypeAndTime[item.shopType];}dateArray.value.forEach((date) => {if (!item.data[date]) {item.data[date] = 0;}});item.data = Object.entries(item.data).sort(([keyA], [keyB]) => new Date(keyA) - new Date(keyB)).map(([key, value]) => value);});});
};
const setOptions3 = () => {chartInstance3.value.setOption({title: {text: "商家入驻数据明细",},tooltip: {trigger: "axis",axisPointer: {type: "cross",},},legend: {data: ServiceCategoryList.value.map((item) => item.name),},grid: {left: "3%",right: "4%",bottom: "3%",containLabel: true,},xAxis: {type: "category",boundaryGap: false,data: dateArray.value,},yAxis: {type: "value",},series: [...ServiceCategoryList.value],});
};
onMounted(async () => {await getShopCategory();await getShopList();chartInstance3.value = echarts.init(chartContainer3.value);setOptions3();
});
onUnmounted(() => {// 组件卸载时销毁图表实例chartInstance3.value.dispose();
});
</script>

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

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

相关文章

FPGA-Verilog-Vivado-软件使用

这里写目录标题 1 软件配置2 FPGA-7000使用2.1 运行启动方式 1 软件配置 编辑器绑定为Vscode&#xff0c;粘贴VS code运行文件的目录&#xff0c;后缀参数保持不变&#xff1a; 如&#xff1a; D:/Users/xdwu/AppData/Local/Programs/Microsoft VS Code/Code.exe [file name]…

(19)夹钳(用于送货)

文章目录 前言 1 常见的抓手参数 2 参数说明 前言 Copter 支持许多不同的抓取器&#xff0c;这对送货应用和落瓶很有用。 按照下面的链接&#xff08;或侧边栏&#xff09;&#xff0c;根据你的设置了解配置信息。 Electro Permanent Magnet v3 (EPMv3)Electro Permanent M…

职业教育人工智能实验实训室建设应用案例

随着人工智能技术的快速发展&#xff0c;其在职业教育领域的应用逐渐深入。唯众作为一家专注于教育技术领域的企业&#xff0c;积极响应国家关于人工智能教育的政策号召&#xff0c;通过建设人工智能实验实训室&#xff0c;为学生提供了一个实践操作与创新思维相结合的学习平台…

34 超级数据查看器 关联图片

超级数据查看器app&#xff08;excel工具&#xff0c;数据库软件&#xff0c;表格app&#xff09; 关联图片讲解 点击 打开该讲的视频 点击访问app下载页面 豌豆荚 下载地址 大家好&#xff0c;今天我们讲一下超级数据查看器的关联图片功能 这个功能能让表中的每一条信息&…

数据结构-散列表(hash table)

6.1 散列表的概念 散列表又叫哈希&#xff08;hash&#xff09;表&#xff0c;是根据键&#xff08;key&#xff09;直接访问在内存存储位置的值&#xff08;value&#xff09;的数据结构&#xff0c;由数组演化而来&#xff08;根据数组支持按照下标进行随机访问数据的特性&a…

力扣爆刷第163天之TOP100五连刷81-85(回文链表、路径和、最长重复子数组)

力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09; 文章目录 力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09;一、234. 回文链表二、112. 路径总和三、169. 多数元素四、662. 二叉树…

Python高级(三)_正则表达式

Python高级-正则表达式 第三章 正则表达式 在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验。 1、正则表达式概述 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、…

PostgreSql中的JSON数据类型

PostgreSQL 提供了两种 JSON 数据类型&#xff1a;JSON 以及 JSONB。这两种类型主要的区别在于数据存储格式&#xff0c;JSONB 使用二进制格式存储数据&#xff0c;更易于处理。 PostgreSQL 推荐优先选择 JSONB 数据类型。 两种数据类型之间的区别&#xff1a; 功能JSONJSONB存…

网络建设与运维23国赛网络运维正式赛题解析

竞赛环境请看主页&#xff01; 23国赛网络运维 任务描述&#xff1a;某集团公司在更新设备后&#xff0c;路由之间无法正常通信&#xff0c;请修 复网络达到正常通信。 &#xff08;1&#xff09; 请在server1“管理员”下拉菜单中选择“镜像”选项卡&#xff0c;点 击 “创…

超声波眼镜清洗机有用吗?四大主流超声波清洗机品牌整理测评

长期佩戴的眼镜&#xff0c;若不定期清洗&#xff0c;不仅镜片会逐渐积聚油脂、灰尘&#xff0c;影响透光率&#xff0c;使视物模糊&#xff0c;更严重的是&#xff0c;眼镜上日益增加的微小杂质和细菌可能会逐渐影响到眼睛健康&#xff0c;导致视力下降、眼部疾病等问题。 这…

Go 1.19.4 函数-Day 08

1. 函数概念和调用原理 1.1 基本介绍 函数是基本的代码块&#xff0c;用于执行一个任务。 Go 语言最少有个 main() 函数。 你可以通过函数来划分不同功能&#xff0c;逻辑上每个函数执行的是指定的任务。 函数声明告诉了编译器函数的名称&#xff0c;返回类型&#xff0c;和参…

STM32 - PWR 笔记

PWR&#xff08;Power Control&#xff09;电源控制 PWR 负责管理 STM32 内部的电源供电部分&#xff0c;可以实现 可编程电压监测器 和 低功耗模式 的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上升到PVD…

usbserver工程师手记(三)手工开通 OTP功能

1、设定密钥&#xff0c;用户自行选择一个密钥&#xff0c;以下以密钥为 EAZAYOKNGETBOPC5 为例说明 2、usb server 配置otp 密钥&#xff0c;目前还没有UI 界面开通&#xff0c;后续版本会支持从管理界面开通 curl -X POST -H Content-Type: application/json -H Accept: app…

Centos7下zabbix安装与部署

Centos7下zabbix安装与部署 一、Zabbix介绍 1、zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案 2、zabbix能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各…

活动策划秘籍:如何让企业活动引爆市场?

作为一个活动策划&#xff0c;我的经验是&#xff0c;活动策划是一场精心编排的交响乐&#xff0c;每一个音符都要恰到好处。 想要做好企业活动策划工作的关键在于综合考虑多个方面&#xff0c;并确保每个环节的顺畅执行。 以下是7个关键要素&#xff0c;只要用心体会&#x…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥派生(C/C++)】

密钥派生(C/C) 以HKDF256密钥为例&#xff0c;完成密钥派生。具体的场景介绍及支持的算法规格&#xff0c;请参考[密钥生成支持的算法]。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 生成密钥 指定密钥别名。 初始化密钥属…

通过电压差判定无源晶振是否起振正确吗?

在电子工程中&#xff0c;无源晶振作为许多数字电路的基础组件&#xff0c;其是否成功起振对于系统的正常运行至关重要。然而&#xff0c;通过简单检测晶振两端的电压差来判断晶振是否工作&#xff0c;这一方法存在一定的误区&#xff0c;晶发电子将深入探讨这一话题&#xff0…

2008年下半年软件设计师【下午题】真题及答案

文章目录 2008年下半年软件设计师下午题--真题2008年下半年软件设计师下午题--答案 2008年下半年软件设计师下午题–真题 2008年下半年软件设计师下午题–答案

四川赤橙宏海商务信息咨询有限公司抖音电商服务靠谱吗?

在数字化浪潮席卷全球的今天&#xff0c;电商行业蓬勃发展&#xff0c;各种新兴电商平台层出不穷。其中&#xff0c;抖音电商以其独特的社交属性和庞大的用户基础&#xff0c;迅速崛起为行业新星。四川赤橙宏海商务信息咨询有限公司&#xff0c;作为专注于抖音电商服务的佼佼者…

个人怎么交易现货黄金:加速形态

我们作为普通个人&#xff0c;在现货黄金市场中交易就需要掌握相应的现货黄金投资技巧。下面我们就来介绍一个&#xff0c;个人怎么交易现货黄金的形态——加速形态。 加速形态是用于判断市场趋势力竭的情况&#xff0c;这种趋势可以是上升&#xff0c;也可以是下跌。但是要注意…