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.pswp.cn/diannao/44966.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/44966.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/44966.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RDD 專項練習

RDD 專項練習 現有分數信息文件 scores.txt 班級ID 姓名 年齡 性別 科目 成績 12 張三 25 男 chinese 50 12 張三 25 男 math 60 12 張三 25 男 english 70 12 李四 20 男 chinese 50 12 李四 20 男 math 50 12 李四 20 男 english 50 12 王芳 19 女 chinese 70 12 王芳 19 女…

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]…

從技術到管理:你必須知道的七個轉變

在職業生涯的道路上&#xff0c;很多技術骨干會逐步轉向管理崗位。這不僅是職位的晉升&#xff0c;更是角色、思維和能力的全方位轉變。以下是七個關鍵的轉變&#xff0c;幫助技術人員順利完成這一跨越。 一、從個人貢獻者到團隊領導者的轉變 在技術崗位上&#xff0c;成功往…

(19)夾鉗(用于送貨)

文章目錄 前言 1 常見的抓手參數 2 參數說明 前言 Copter 支持許多不同的抓取器&#xff0c;這對送貨應用和落瓶很有用。 按照下面的鏈接&#xff08;或側邊欄&#xff09;&#xff0c;根據你的設置了解配置信息。 Electro Permanent Magnet v3 (EPMv3)Electro Permanent M…

bug記錄 qInstallMessageHandler的使用

QT (純C)項目 ‘Qxxx‘ file not found 和 編譯報錯問題(已解決)_qt頭文件file not found-CSDN博客 qInstallMessageHandler&#xff08;指針函數參數&#xff09; 需要靜態指針&#xff0c;這個函數 #include <iostream> #include "singleton.h" #include &…

Linux操作系統CentOS如何更換yum鏡像源

簡介 CentOS&#xff0c;是基于Red Hat Linux提供的可自由使用源代碼的企業級Linux發行版本&#xff1b;是一個穩定&#xff0c;可預測&#xff0c;可管理和可復制的免費企業級計算平臺。 下載地址: centos安裝包下載_開源鏡像站-阿里云 相關倉庫&#xff1a; CentOS過期源&…

職業教育人工智能實驗實訓室建設應用案例

隨著人工智能技術的快速發展&#xff0c;其在職業教育領域的應用逐漸深入。唯眾作為一家專注于教育技術領域的企業&#xff0c;積極響應國家關于人工智能教育的政策號召&#xff0c;通過建設人工智能實驗實訓室&#xff0c;為學生提供了一個實踐操作與創新思維相結合的學習平臺…

C++ STL iter_swap用法和實現

一&#xff1a;功能 交換兩個迭代器指向的元素值&#xff0c;一般用在模板中 二&#xff1a;使用 #include <vector> #include <iostream>template <typename It, typename Cond>requires std::forward_iterator<It> && std::indirectly_swa…

富格林:曝光糾正安全交易誤區

富格林指出&#xff0c;貴金屬投資是許多投資者追求資產多樣化和風險管理的重要途徑。然而&#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…

windows腳本獲取 svn版本號

簡介 需要使用項目中svn的最新版本號 命令 set svnURL"URL" svn info %svnURL% | findstr "Revision:" > Version.txt for /f "token2 delims " %%i in (Version.txt) do set rev%%i echo %rev% pause

力扣爆刷第163天之TOP100五連刷81-85(回文鏈表、路徑和、最長重復子數組)

力扣爆刷第163天之TOP100五連刷81-85&#xff08;回文鏈表、路徑和、最長重復子數組&#xff09; 文章目錄 力扣爆刷第163天之TOP100五連刷81-85&#xff08;回文鏈表、路徑和、最長重復子數組&#xff09;一、234. 回文鏈表二、112. 路徑總和三、169. 多數元素四、662. 二叉樹…

洛谷 B4006 [GESP202406 四級] 寶箱

題目描述 小楊發現了 &#x1d45b; 個寶箱&#xff0c;其中第 &#x1d456; 個寶箱的價值是 &#x1d44e;&#x1d456;?。 小楊可以選擇一些寶箱放入背包并帶走&#xff0c;但是小楊的背包比較特殊&#xff0c;假設小楊選擇的寶箱中最大價值為 &#x1d465;&#xff0c…

next input代碼嘗試編寫

使用有限狀態機&#xff08;FSM&#xff09;可以使代碼結構更清晰&#xff0c;特別是處理復雜的狀態和過渡時。以下是如何根據你提供的步驟&#xff0c;用有限狀態機來實現自動校準和中斷觸發邏輯的示例代碼。 狀態定義 IDLE: 空閑狀態&#xff0c;等待數據輸入。CALIBRATING…

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;和參…