国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

記錄--Vue3 封裝 ECharts 通用組件

這篇具有很好參考價(jià)值的文章主要介紹了記錄--Vue3 封裝 ECharts 通用組件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

這里給大家分享我在網(wǎng)上總結(jié)出來(lái)的一些知識(shí),希望對(duì)大家有所幫助

記錄--Vue3 封裝 ECharts 通用組件

按需導(dǎo)入的配置文件

配置文件這里就不再贅述,內(nèi)容都是一樣的,主打一個(gè)隨用隨取,按需導(dǎo)入。

import * as echarts from "echarts/core";
// 引入用到的圖表
import { LineChart, type LineSeriesOption} from "echarts/charts";
// 引入提示框、數(shù)據(jù)集等組件
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  type TooltipComponentOption,
  type TitleComponentOption,
  type GridComponentOption,
  type LegendComponentOption
} from "echarts/components";
// 引入標(biāo)簽自動(dòng)布局、全局過(guò)渡動(dòng)畫(huà)等特性
import { LabelLayout } from "echarts/features";
// 引入 Canvas 渲染器,必須
import { CanvasRenderer } from "echarts/renderers";

import type { ComposeOption } from "echarts/core";

// 通過(guò) ComposeOption 來(lái)組合出一個(gè)只有必須組件和圖表的 Option 類型
export type ECOption = ComposeOption<
  | LineSeriesOption
  | GridComponentOption
  | TitleComponentOption
  | TooltipComponentOption
  | LegendComponentOption
>;

// 注冊(cè)必須的組件
echarts.use([
  LineChart,
  TitleComponent,
  TooltipComponent,
  GridComponent,
  CanvasRenderer,
  LabelLayout,
  LegendComponent
]);

export default echarts;

基本封裝

DOM結(jié)構(gòu)和實(shí)例化

<script setup lang="ts">
import { Ref, onMounted, onBeforeUnmount } from "vue";
import { type EChartsType } from "echarts/core";

interface Props {
  option: ECOption;
  theme?: Object | string; // 主題
}

const props = withDefaults(defineProps<Props>(), {
  theme: null
});

const chartRef = ref<Ref<HTMLDivElement>>(null);
const chartInstance = ref<EChartsType>();

// 繪制
const draw = () => {
  if (chartInstance.value) {
    chartInstance.value.setOption(props.option, { notMerge: true });
  }
};

// 初始化
const init = () => {
  if (!chartRef.value) return;

  // 校驗(yàn) Dom 節(jié)點(diǎn)上是否已經(jīng)掛載了 ECharts 實(shí)例,只有未掛載時(shí)才初始化
  chartInstance.value = echarts.getInstanceByDom(chartRef.value);
  if (!chartInstance.value) {
    chartInstance.value = echarts.init(
        chartRef.value,
        props.theme,
        { renderer: "canvas" }
    );

    draw();
  }
};

watch(props, () => {
  draw();
});

onMounted(() => {
  init();
});

onBeforeUnmount(() => {
  // 容器被銷毀之后,銷毀實(shí)例,避免內(nèi)存泄漏
  chartInstance.value?.dispose();
});
</script>

<template>
  <div id="echart" ref="chartRef" :style="{ width: '100px', height: '120px' }" />
</template>

chartRef:當(dāng)前的 DOM 節(jié)點(diǎn),即 ECharts 的容器;

chartInstance:當(dāng)前 DOM 節(jié)點(diǎn)掛載的 ECharts 實(shí)例,可用于調(diào)用實(shí)例上的方法,注冊(cè)事件,自適應(yīng)等;

draw:用于繪制 ECharts 圖表,本質(zhì)是調(diào)用實(shí)例的 setOption 方法;

init:初始化,在此獲取 DOM 節(jié)點(diǎn),掛載實(shí)例,注冊(cè)事件,并調(diào)用 draw 繪制圖表。

Cannot read properties of undefined (reading 'type')

請(qǐng)注意,上述代碼目前還不能正常運(yùn)行,這里會(huì)遇到第一個(gè)坑 —— 圖表無(wú)法顯示,這是 React 中沒(méi)有碰到的:

記錄--Vue3 封裝 ECharts 通用組件

?出現(xiàn)這種問(wèn)題是因?yàn)椋覀兪褂?ref?接收了?echarts.init?的實(shí)例。這會(huì)導(dǎo)致?chartInstance?被代理成為響應(yīng)式對(duì)象,影響了 ECharts 對(duì)內(nèi)部屬性的訪問(wèn)。Echarts 官方 FAQ?也闡述了該問(wèn)題:

記錄--Vue3 封裝 ECharts 通用組件

?

所以,我們有兩種解決方法:

  1. 使用 shallowRef 替換 ref
  2. 使用 ref + markRaw。

shallowRef 和?ref()?不同之處在于,淺層 ref 的內(nèi)部值將會(huì)原樣存儲(chǔ)和暴露,并且不會(huì)被深層遞歸地轉(zhuǎn)為響應(yīng)式。只有對(duì)?.value?的訪問(wèn)是響應(yīng)式的。

而 markRaw 則會(huì)將一個(gè)對(duì)象標(biāo)記為不可被轉(zhuǎn)為代理。返回該對(duì)象本身。在有些值不應(yīng)該是響應(yīng)式的場(chǎng)景中,例如復(fù)雜的第三方類實(shí)例或 Vue 組件對(duì)象,這很有用。

記錄--Vue3 封裝 ECharts 通用組件

?我們這里使用?markRaw?對(duì)?init?進(jìn)行包裹:

chartInstance.value = markRaw(
  echarts.init(
      chartRef.value,
      props.theme,
      { renderer: "canvas" }
  )
);

窗口防抖自適應(yīng)

這里和 React 中就差不多了,主要安利一個(gè) Vue 官方團(tuán)隊(duì)維護(hù)的 hooks 庫(kù):vueuse?。和 React 中的 ahooks 一樣,封裝了很多實(shí)用的 hooks,我們可以使用?useDebounceFn?來(lái)優(yōu)化自適應(yīng)函數(shù):

import { useDebounceFn } from "@vueuse/core";

// 窗口自適應(yīng)并開(kāi)啟過(guò)渡動(dòng)畫(huà)
const resize = () => {
  if (chartInstance.value) {
    chartInstance.value.resize({ animation: { duration: 300 } });
  }
};

// 自適應(yīng)防抖優(yōu)化
const debouncedResize = useDebounceFn(resize, 500, { maxWait: 800 });

onMounted(() => {
  window.addEventListener("resize", debouncedResize);
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", debouncedResize);
});

額外監(jiān)聽(tīng)寬高

目前,圖標(biāo)的大小還是寫(xiě)死的,現(xiàn)在我們支持 props 傳遞寬高來(lái)自定義圖表大小:

interface Props {
  option: ECOption;
  theme?: Object | string;
  width: string;
  height: string;
}

<template>
  <div
    id="echart"
    ref="chartRef"
    :style="{ width: props.width, height: props.height }"
  />
</template>

請(qǐng)注意:在使用時(shí),我們必須指定容器的寬高,否則無(wú)法顯示,因?yàn)閳D表在繪制時(shí)會(huì)自動(dòng)獲取父容器的寬高。

flex/grid 布局下 resize 失效的問(wèn)題

這個(gè)問(wèn)題剛遇到著實(shí)有點(diǎn)蛋疼,摸了蠻久,而 bug 觸發(fā)的條件也比較奇葩,但也比較常見(jiàn):

  1. 在父組件中,復(fù)用多個(gè) ECharts 組件;
  2. 使用了 flex 或 grid 這種沒(méi)有明確給定寬高的布局;

記錄--Vue3 封裝 ECharts 通用組件

此時(shí)會(huì)發(fā)現(xiàn):當(dāng)前窗口放大,正常觸發(fā) resize, 圖表會(huì)隨之放大。但是,此時(shí)再縮小窗口,雖然也會(huì)觸發(fā) resize,但是圖表的大小卻縮不回來(lái)了......

一開(kāi)始還以為是我封裝的寫(xiě)法有問(wèn)題,直到搜到了ECharts 官方的 issues 才發(fā)現(xiàn)原來(lái)不止我一個(gè)遇到了??

記錄--Vue3 封裝 ECharts 通用組件

我的理解是:首先,無(wú)論什么布局 echarts 取的都是 dom 的 clientWidth 和 clientHeight 作為容器寬高。其次,由于 flex、grid 這種布局可以不需要顯示地指定 width、height,這就導(dǎo)致 echarts 在自適應(yīng)的過(guò)程中無(wú)法明確地獲取到容器的寬高,所以即便觸發(fā)了 resize 事件,但是重繪的圖表還是之前默認(rèn)的寬高。

解決方案

給每個(gè) flex-itemgrid-item 自適應(yīng)的寬或者高都設(shè)置一個(gè)最小值(我項(xiàng)目中的寬是自適應(yīng)的,高度是固定的):

.chart-item {
    flex: 1;
    min-width: 30vh;
    height: 300px;
}

這里不得不吐槽下,早在2017年就有人提出過(guò)這個(gè)問(wèn)題,2020年終于給出了解釋,但是現(xiàn)在都2023了,這個(gè)問(wèn)題還沒(méi)有得到解決,issues 還 open 著 ??

綁定鼠標(biāo)事件

我們可以給圖表中的一些組件添加額外的交互,比如給 title 鼠標(biāo) hover 事件等,記得在需要使用事件的組件上添加 triggerEvent: true 屬性。

我們演示鼠標(biāo)移入 title 顯示 y軸 name,鼠標(biāo)移出 title 隱藏 y軸 name 的需求:

interface Props {
  // 略...
  onMouseover?: (...args: any[]) => any;
  onMouseout?: (...args: any[]) => any;
}

const init = () => {
    // 略......

    // 綁定 mousehover 事件:
    if (props.onMouseover) {
      chartInstance.value.on("mouseover", (event: Object) => {
        props.onMouseover(event, chartInstance.value, props.option);
      });
    }
    
    // 綁定 mouseout 事件:
    if (props.onMouseout) {
      chartInstance.value.on("mouseout", (event: Object) => {
        props.onMouseout(event, chartInstance.value, props.option);
      });
    }
  }
};
在上述注冊(cè)的回調(diào)事件中,我們將 ECharts 實(shí)例和傳入的 option 重新傳出去,這樣可以就在外面重新配置 option 并調(diào)用實(shí)例的方法進(jìn)行圖表的重繪了:
import Chart from "@/components/BaseChart/index.vue";
import type { EChartsType } from "echarts/core";
import type { ECOption } from "@/components/BaseChart/config";
import type { YAXisOption } from "echarts/types/dist/shared";

// 鼠標(biāo)移入,顯示y軸 name
const onMouseover = (chart: EChartsType, option: ECOption) => {
  (option.yAxis as YAXisOption).nameTextStyle.color = "#ccc";
  // 重繪圖表
  chart.setOption(option);
};

// 鼠標(biāo)移出,隱藏y軸 name
const onMouseout = (chart: EChartsType, option: ECOption) => {
  (option.yAxis as YAXisOption).nameTextStyle.color = "transparent";
  chart.setOption(option);
};

<template>
    <Chart
        width="100%"
        height="305px"
        :option="{
            // 略......
            title: {
                text: "標(biāo)題",
                triggerEvent: true
            },
        }"
        :on-mouseover="onMouseover"
        :on-mouseout="onMouseout"
    />
</template>

展示 loading 動(dòng)畫(huà)

支持受控的 loading 動(dòng)畫(huà)

interface Props {
  // 略...
  loading?: boolean; // 受控
}

const props = withDefaults(defineProps<Props>(), {
  theme: null,
  loading: false
});

watch(
  () => props.loading,
  loading => {
    loading
      ? chartInstance.value.showLoading()
      : chartInstance.value.hideLoading();
  }
);

暴露實(shí)例方法

對(duì)父組件暴露獲取 ECharts 實(shí)例的方法,讓父組件可直接通過(guò)實(shí)例調(diào)用原生函數(shù)。

defineExpose({
  getInstance: () => chartInstance.value,
  resize,
  draw
});

順便提一下,?defineExpose?是在?<script setup>?才能使用的編譯器宏,用來(lái)顯式指定需要暴露給父組件的屬性。

完整代碼

太長(zhǎng)了,貼出來(lái)沒(méi)人會(huì)細(xì)看,有需要的直接自取,親測(cè)有效,啟動(dòng)項(xiàng)目就能看到,快去魔改吧??github

本文轉(zhuǎn)載于:

https://juejin.cn/post/7245183742264377401

如果對(duì)您有所幫助,歡迎您點(diǎn)個(gè)關(guān)注,我會(huì)定時(shí)更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進(jìn)步。

?記錄--Vue3 封裝 ECharts 通用組件文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-490576.html

到了這里,關(guān)于記錄--Vue3 封裝 ECharts 通用組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 整體認(rèn)識(shí)和路由配置、基礎(chǔ)數(shù)據(jù)渲染、熱榜區(qū)域?qū)崿F(xiàn)、圖片預(yù)覽組件封裝、認(rèn)識(shí)SKU組件、通用組件統(tǒng)一注冊(cè)全局(詳情頁(yè))【Vue3】

    整體認(rèn)識(shí)和路由配置、基礎(chǔ)數(shù)據(jù)渲染、熱榜區(qū)域?qū)崿F(xiàn)、圖片預(yù)覽組件封裝、認(rèn)識(shí)SKU組件、通用組件統(tǒng)一注冊(cè)全局(詳情頁(yè))【Vue3】

    整體業(yè)務(wù)認(rèn)識(shí) 路由配置 準(zhǔn)備組件模板 配置路由 綁定模板測(cè)試跳轉(zhuǎn) 封裝接口 獲取數(shù)據(jù)渲染模版 思考:渲染模版時(shí)遇到對(duì)象的多層屬性訪問(wèn)可能出現(xiàn)什么問(wèn)題? 模塊實(shí)現(xiàn)整體分析 結(jié)論:兩塊熱榜相比, 結(jié)構(gòu)一致,標(biāo)題title和列表內(nèi)容不同 渲染基礎(chǔ)熱榜數(shù)據(jù) 1- 準(zhǔn)備模版 2- 封

    2024年02月15日
    瀏覽(36)
  • Vue組件封裝:基于Vue3+wangeditor富文本組件二次封裝

    Vue組件封裝:基于Vue3+wangeditor富文本組件二次封裝

    1.簡(jiǎn)介 ? ? ? ? 開(kāi)源 Web 富文本編輯器,開(kāi)箱即用,配置簡(jiǎn)單。一個(gè)產(chǎn)品的價(jià)值,就在于解決用戶的問(wèn)題,提高效率、降低成本、增加穩(wěn)定性和擴(kuò)展性。wangEditor 不是為了做而做,也不是單純的模仿誰(shuí),而是經(jīng)過(guò)上述問(wèn)題分析之后,給出一個(gè)系統(tǒng)的解決方案。旨在真正去解決用

    2024年04月08日
    瀏覽(97)
  • 記錄vue3+echarts搭建數(shù)據(jù)可視化頁(yè)面!

    記錄vue3+echarts搭建數(shù)據(jù)可視化頁(yè)面!

    提示:記錄一下寫(xiě)頁(yè)面的時(shí)候遇到過(guò)的一些小問(wèn)題! 頁(yè)面布局就是簡(jiǎn)單的用了個(gè)三欄式布局,在寫(xiě)頁(yè)面的過(guò)程中對(duì)于多個(gè)頁(yè)面共同使用的部分要注意善用組件復(fù)用,避免寫(xiě)冗余重復(fù)的代碼! 比如說(shuō)對(duì)于需要重復(fù)使用的圖表容器,可以將其注冊(cè)為全局組件V3Echarts.vue,當(dāng)需要表

    2024年02月16日
    瀏覽(22)
  • vue3 echart組件封裝

    項(xiàng)目中用到了很多echart圖表,進(jìn)行了簡(jiǎn)單的組件封裝,主要包含以下功能: 創(chuàng)建圖表實(shí)例,渲染圖表 支持傳入自定義函數(shù),可拿到圖表實(shí)例,實(shí)現(xiàn)個(gè)性化功能 支持配置更新后圖表自動(dòng)刷新,可配置是清空后再刷新 loading狀態(tài)控制 resize時(shí)圖表更新 支持餅圖默認(rèn)高亮功能 echa

    2024年03月09日
    瀏覽(23)
  • vue3范圍選擇組件封裝

    vue3范圍選擇組件封裝

    個(gè)人項(xiàng)目地址:?SubTopH前端開(kāi)發(fā)個(gè)人站 (自己開(kāi)發(fā)的前端功能和UI組件,一些有趣的小功能,感興趣的伙伴可以訪問(wèn),歡迎提出更好的想法,私信溝通,網(wǎng)站屬于靜態(tài)頁(yè)面) SubTopH前端開(kāi)發(fā)個(gè)人站 https://subtop.gitee.io/subtoph.github.io/#/home 實(shí)現(xiàn)效果 直接上代碼 組件文件 ?組件使用

    2024年02月11日
    瀏覽(21)
  • vue3組件封裝系列-表單請(qǐng)求

    vue3組件封裝系列-表單請(qǐng)求

    我們?cè)陂_(kāi)發(fā)一些后臺(tái)管理系統(tǒng)時(shí),總是會(huì)寫(xiě)很多的列表查詢頁(yè)面,如果不封裝組件,就會(huì)無(wú)限的復(fù)制粘貼,而且頁(yè)面很冗余,正常情況下,我們都是要把組件進(jìn)行二次封裝,來(lái)達(dá)到我們想要效果。這里我分享一下我近期封裝的關(guān)于列表的組件封裝。 vue3+element-plus srccomponents

    2024年04月23日
    瀏覽(18)
  • vue3組件二次封裝Ui處理

    vue3組件二次封裝Ui處理

    在Vue開(kāi)發(fā)中,我們常常需要使用UI框架提供的組件。但是UI框架的組件可能并不符合我們的需求,這時(shí)候就需要進(jìn)行二次封裝。下面是一些關(guān)于Vue組件二次封裝Ui處理的技巧: 子組件代碼: 父組件使用: 如果使用props接收弊端: 基本上組件不會(huì)只有一兩個(gè)屬性,屬性多的話接

    2023年04月14日
    瀏覽(32)
  • vue3自定義封裝組件:消息提示、輪播圖、加載更多、骨架屏組件

    定義組件:src/components/library/xtx-infinite-loading.vue 注冊(cè)組件:src/components/library/index.js ?引用組件:src/main.js 使用組件: .vue文件 首先是輪播圖的樣式:src/components/library/xtx-carousel.vue? 然后是輪播圖的結(jié)構(gòu)與邏輯封裝:src/components/library/xtx-carousel.vue 插件注冊(cè):src/components/library

    2024年02月12日
    瀏覽(17)
  • 【TSX】vue3 + element-ui + tsx 通用表格組件

    簡(jiǎn)介: 基于 vue3 + el-table 封裝的通用表格組件 的 tsx寫(xiě)法,想要參考模板寫(xiě)法的可以到我另一篇博客喔~ TS + vue3.2 + vite2 + element-plus 通用表格組件封裝 話不多說(shuō),本組件分為四部分: 組件調(diào)用: ? 屬性及方法使用說(shuō)明: 注意:如果你在使用 Sortable插件想要拖動(dòng)排序表格時(shí),t

    2024年02月15日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包