最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從Echarts報錯中學習Vue3?ref和shallowRef區(qū)別及其組件二次封裝demo

 更新時間:2023年11月07日 09:01:18   作者:水冗水孚  
這篇文章主要介紹了從Echarts報錯中學習Vue3?ref和shallowRef區(qū)別及其組件二次封裝demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

報錯場景

Uncaught TypeError: Cannot read properties of undefined (reading 'type') at LineView2.render (LineView.js:567:36) echarts.js:976

上述是報錯信息

  • 筆者簡單封裝一個Echarts組件,代碼文末附上,使用Vue3搭配Echarts5
  • 在初始化echarts.init圖表時,沒有問題,但是當進行自適應resize的時候報錯了
  • 報錯截圖如下:

報錯截圖

報錯原因分析

  • 報錯的原因是Echarts初始化的實例變量受到了Vue響應式ref的影響——啥意思呢?就是
  • 響應式的原理就是代理,也就是說,通過ref函數(shù)加工代理的Echarts實例,已經(jīng)不是原來的實例了。通俗而言,就是ref函數(shù)“克隆”了一份Echarts本體實例,本體實例自帶resize方法,但是代理克隆體上的resize方法可能克隆的不太完美【這樣描述不太嚴謹,反正是這個意思】
  • 也就可能導致了ref函數(shù)克隆體的Echarts實例在調(diào)用時出錯

解決方案

  • 既然Echarts初始化的實例變量會受到Vue響應式的影響
  • 那么我們在存儲Echarts的時候,就不存到Vue的響應式變量里面即可

如下:

思考,難道所有的變量,都要,都得,都必須通過ref或者reactive定義成響應式的嗎?

原來的寫法用ref存儲:不建議

import * as echarts from "echarts";
const eChaDom = ref(null); // 用于初始化Echarts畫布需要的dom元素
const chart = ref(null) // 用于存儲Echarts
chart.value = echarts.init(eChaDom.value) // 初始化實例

解決方案一:直接使用普通變量來存儲Echarts實例

import * as echarts from "echarts";
let eChaDom = document.querySelector('.eChaDom'); // 用于初始化Echarts畫布需要的dom元素
let chart = null // 用于存儲Echarts
chart = echarts.init(eChaDom) // 初始化實例

解決方案二:使用淺層響應式shallowRef進行存儲Echarts實例

  • 我們知道ref響應式有些過頭了,稍微一變都能感應到,而Echart的實例是不可變的
  • 你變我不變,就容易打架出問題
  • 所以,若是不想使用普通變量來存儲Echarts實例,使用shallowRef進行定義存儲也是可以的
  • 如下:
import * as echarts from "echarts";
const eChaDom = shallowRef(null); // 用于初始化Echarts畫布需要的dom元素
const chart = shallowRef(null) // 用于存儲Echarts
chart.value = echarts.init(eChaDom.value) // 初始化實例

解決方案三:依舊用ref但是搭配markRaw強制返回自身,不讓代理克隆一份

import { ref, markRaw, shallowRef } from "vue";
import * as echarts from "echarts";
const eChaDom = ref(null); // 用于初始化Echarts畫布需要的dom元素
const chart = ref(null) // 用于存儲Echarts
chart.value = markRaw(echarts.init(eChaDom.value)) // 初始化實例
  • 這種方式有些多此一舉了,本來ref就是要代理克隆的一份,我們再使用markRaw去強制不允許代理克隆一份
  • 這種方式不太推薦
  • 屬于奇葩的操作

思考ref和shallowRef應用場景————性能優(yōu)化

  • 我們平常定義一個變量,可以將其定義成響應式的,或者非響應式的
  • 定義成響應式的是為了后續(xù)改它,自動觸發(fā)頁面視圖更新
  • 可是啊,在Echarts中,初始化的實例一般也不用去更改,更多的是去調(diào)用其自帶的方法
  • 所以我們沒必要還用ref將其定義響應式存儲
  • 直接定義一個非響應式數(shù)據(jù)去存儲一下也沒問題的
  • 當然,折中一下,就是用淺層響應式的shallowRef來定義存儲吧

實際上,這也是性能優(yōu)化提升的一種方式

因為ref是把一個變量遞歸深層次加工成響應式【耗時不少】,而shallowRef操作加工【耗時少】

我們看官方的shallowRef和markRaw這兩張圖,就能夠理解明白了:

圖:

圖:

官方地址在這

小結(jié)

  • 響應式變量有對應的好處、非響應式變量也有其優(yōu)點
  • 我們應該根據(jù)實際情況,去靈活定義一個變量到底是響應式還是非響應式的【亦或是淺層響應式的】
  • 本文就是一個實際情況【shallowRef折中定義一個淺層響應式的Echarts實例的變量】
  • 時間允許下,可以多研究研究一些報錯的具體原因,這樣可以加深我們對于技術的理解

當然,github就這個問題,也有對應的issue。地址在這里

一句話總結(jié),某些大一些的、不需要更改的實例化的數(shù)據(jù)對象,就不需使用ref定義成深層響應式啦(直接用普通變量存儲也無妨)。若是依舊想定義成響應式的,那就使用shallowRef即可

  • 一句話總結(jié),某些大一些的、不需要更改的實例化的數(shù)據(jù)對象,就不需使用ref定義成深層響應式啦
  • 直接用普通變量存儲也無妨
  • 若是依舊想定義成響應式的,那就使用shallowRef即可

嗯,這樣記,通俗易懂

封裝的Echarts組件,可復現(xiàn)對應報錯bug

組件二次封裝Echarts代碼

<template>
    <div ref="eChaDom" :style="{ height: h }" />
</template>
<script setup>
import { watch, onMounted, onBeforeUnmount, ref, shallowRef } from "vue";
import * as echarts from "echarts";
import debounce from 'lodash/debounce'
const props = defineProps({
    h: {
        type: String,
        default: '360px'
    },
    options: {
        type: Object,
        default: () => ({})
    },
    theme: {
        type: String,
        default: 'dark'
    }
})
// const eChaDom = ref(null); // 這樣resize有報錯
// const chart = ref(null)
const eChaDom = shallowRef(null); // 這樣resize就沒報錯了
const chart = shallowRef(null)
const init = () => {
    chart.value = echarts.init(eChaDom.value, props.theme)
    chart.value.setOption(props.options);
    window.addEventListener('resize', debounce(resizeFn, 360))
}
const resizeFn = () => {
    chart.value.resize()
}
onMounted(() => {
    init()
})
watch(
    () => props.options,
    (newOptions) => {
        chart.value.setOption(newOptions);
    },
    { deep: true }
)
onBeforeUnmount(() => {
    window.removeEventListener('resize', resizeFn)
})
</script>

使用組件

<template>
    <div class="tenBox">
        <eCha :options="options" h="600px" />
    </div>
</template>
<script setup>
import eCha from "@/components/eCha/index.vue";
const options = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            type: 'line',
            smooth: true
        }
    ]
}

以上就是從Echarts報錯中學習Vue3 ref和shallowRef區(qū)別及其組件二次封裝demo的詳細內(nèi)容,更多關于Vue3 ref shallowRef區(qū)別的資料請關注腳本之家其它相關文章!

相關文章

  • Vue是怎么渲染template內(nèi)的標簽內(nèi)容的

    Vue是怎么渲染template內(nèi)的標簽內(nèi)容的

    這篇文章主要介紹了Vue是怎么渲染template內(nèi)的標簽內(nèi)容的,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • vue 本地環(huán)境跨域請求proxyTable的方法

    vue 本地環(huán)境跨域請求proxyTable的方法

    今天小編就為大家分享一篇vue 本地環(huán)境跨域請求proxyTable的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue+Nodejs使用WebSocket創(chuàng)建一個簡易聊天室教程

    Vue+Nodejs使用WebSocket創(chuàng)建一個簡易聊天室教程

    這篇文章主要介紹了Vue+Nodejs使用WebSocket創(chuàng)建一個簡易聊天室教程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Vue項目頁面跳轉(zhuǎn)時瀏覽器窗口上方顯示進度條功能

    Vue項目頁面跳轉(zhuǎn)時瀏覽器窗口上方顯示進度條功能

    這篇文章主要介紹了Vue項目頁面跳轉(zhuǎn)時瀏覽器窗口上方顯示進度條功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • vue3監(jiān)聽resize窗口事件(離開頁面要銷毀窗口事件)

    vue3監(jiān)聽resize窗口事件(離開頁面要銷毀窗口事件)

    這篇文章主要給大家介紹了關于vue3監(jiān)聽resize窗口事件(離開頁面要銷毀窗口事件)的相關資料,vue是單頁面應用,路由切換后,定時器并不會自動關閉,需要手動清除,當頁面被銷毀時,清除定時器即可,需要的朋友可以參考下
    2023-11-11
  • Vue使用視頻作為網(wǎng)頁背景的實現(xiàn)指南

    Vue使用視頻作為網(wǎng)頁背景的實現(xiàn)指南

    在現(xiàn)代網(wǎng)頁設計中,視頻背景逐漸成為一種流行的設計趨勢,它不僅能夠提升網(wǎng)頁的動態(tài)效果,還可以在視覺上抓住用戶的注意力,本文將詳細講解如何在頁面中使用視頻作為背景,并確保內(nèi)容可見、頁面元素布局合理,需要的朋友可以參考下
    2024-10-10
  • 聊一聊Vue.js過渡效果

    聊一聊Vue.js過渡效果

    這篇文章主要和大家一起聊一聊Vue.js過渡效果、CSS 過渡效果、純 JavaScript過渡效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解vue如何獲取當前系統(tǒng)時間

    詳解vue如何獲取當前系統(tǒng)時間

    這篇文章主要詳細介紹了vue如何獲取當前系統(tǒng)時間,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • 解決vue-seamless-scroll滾動加點贊銜接處數(shù)據(jù)不同步問題

    解決vue-seamless-scroll滾動加點贊銜接處數(shù)據(jù)不同步問題

    這篇文章主要介紹了解決vue-seamless-scroll滾動加點贊銜接處數(shù)據(jù)不同步問題,初步判斷可能是因為下方懸接vue-seamless-scroll是靜態(tài)的,沒同步DOM,本文給大家分享解決方法,感興趣的朋友一起看看吧
    2021-11-11
  • uniapp+vue3實現(xiàn)自定義封裝支付密碼組件

    uniapp+vue3實現(xiàn)自定義封裝支付密碼組件

    本文介紹使用Vue3語法在uniapp中自定義封裝支付密碼組件,通過父組件與子組件的交互實現(xiàn)密碼輸入功能,并附效果圖展示,感興趣的朋友跟隨小編一起看看吧
    2025-08-08

最新評論

泊头市| 翁牛特旗| 渝北区| 台前县| 武功县| 罗江县| 德令哈市| 宜川县| 县级市| 德令哈市| 吕梁市| 张家界市| 赤城县| 双辽市| 班玛县| 津南区| 伊吾县| 西吉县| 昌都县| 奈曼旗| 泰和县| 抚远县| 灵璧县| 五常市| 湖北省| 新兴县| 始兴县| 石城县| 马公市| 昌图县| 鹿泉市| 岱山县| 赤峰市| 阳春市| 南雄市| 呼图壁县| 平邑县| 平和县| 河源市| 定结县| 海原县|