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

DataV?全屏容器組件源碼解析

 更新時間:2023年04月07日 14:17:01   作者:叁兩  
這篇文章主要為大家介紹了DataV?全屏容器組件源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

數(shù)據(jù)可視化頁面一般在瀏覽器中進(jìn)行全屏展示,全屏容器將根據(jù)屏幕比例及當(dāng)前瀏覽器窗口大小,自動進(jìn)行縮放處理。瀏覽器全屏后,全屏容器將充滿屏幕。

接下來我們來一起閱讀下DataV中關(guān)于全屏容器的源碼,看下它是如何實現(xiàn)的。

源碼閱讀(vue2版本)

它的源碼位置

看下它的DOM結(jié)構(gòu),很簡單

<div id="dv-full-screen-container" :ref="ref">
    <template v-if="ready">
      <slot></slot>
    </template>
</div>

源碼分析

接下來重點看下它的JS實現(xiàn),它的代碼中混入了autoResize.js,所以我們需要兩個文件一起看,不然會對突然出現(xiàn)的變量很奇怪。(如果覺得分開不便于閱讀,其實我們可以把它合在一起來閱讀,是一樣的)

梳理下它的執(zhí)行邏輯:

第1步、mounted(組件掛載時,這一時期可對dom進(jìn)行操作)

mounted () {
  const { autoResizeMixinInit } = this
  autoResizeMixinInit()
},

第2步、autoResizeMixinInit函數(shù)

methods: {
    async autoResizeMixinInit () {
      const { initWH, getDebounceInitWHFun, bindDomResizeCallback, afterAutoResizeMixinInit } = this
      await initWH(false)
      getDebounceInitWHFun()
      bindDomResizeCallback()
      if (typeof afterAutoResizeMixinInit === 'function') afterAutoResizeMixinInit()
    },
}

這其中調(diào)用了幾個函數(shù),我們來看看這些函數(shù)的作用。

2.1、initWH函數(shù)

    // 初始化寬高
    initWH (resize = true) {
      const { $nextTick, $refs, ref, onResize } = this
      return new Promise(resolve => {
        $nextTick(_ => {
          const dom = this.dom = $refs[ref]
          this.width = dom ? dom.clientWidth : 0
          this.height = dom ? dom.clientHeight : 0
          if (!dom) { 
            console.warn('DataV: Failed to get dom node, component rendering may be abnormal!')
          } else if (!this.width || !this.height) {
            console.warn('DataV: Component width or height is 0px, rendering abnormality may occur!')
          }
          if (typeof onResize === 'function' && resize) onResize()
          resolve()
        })
      })
    },

這個函數(shù)的作用很簡單,就是在DOM渲染成功后,獲取這個組件dom的寬高,返回一個Promise異步函數(shù),作用就是:保證這個dom已經(jīng)渲染好了,再去執(zhí)行其他函數(shù)。

2.1.1、onResize

    onResize () {
      const { setAppScale } = this
      setAppScale()
    }

resize為true,即窗口大小變化、dom的style改變時要重新設(shè)置dom的縮放比例。

2.2、getDebounceInitWHFun

getDebounceInitWHFun () {
      const { initWH } = this
      this.debounceInitWHFun = debounce(100, initWH)
    },

獲取一個經(jīng)過防抖的initWH函數(shù)。即debounceInitWHFun。

2.3、bindDomResizeCallback

    // 監(jiān)聽dom元素變化
    bindDomResizeCallback () {
      const { dom, debounceInitWHFun } = this
      this.domObserver = observerDomResize(dom, debounceInitWHFun)
      window.addEventListener('resize', debounceInitWHFun)
    },

很重要的一步,其中使用了observerDomResize來對這個組件dom進(jìn)行監(jiān)聽。

需要監(jiān)聽的DOM變化:

  • 窗口大小改變時觸發(fā)的事件
  • dom的樣式改變時觸發(fā)

第一個直接使用window監(jiān)聽resize事件即可。

第二個對dom元素的監(jiān)聽,我們就需要使用MutationObserver來做了。

MutationObserver用來監(jiān)視 DOM 變動。DOM 的任何變動,比如節(jié)點的增減、屬性的變動、文本內(nèi)容的變動都會觸發(fā)MutationObserver事件。

封裝一個observerDomResize函數(shù)來對dom的style屬性變化進(jìn)行監(jiān)聽

export function observerDomResize (dom, callback) {
  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
  const observer = new MutationObserver(callback)
  observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
  return observer
}
  • attributes:屬性的變動
  • attributeFilter:表示需要觀察的特定屬性
  • attributeOldValue:布爾值,表示觀察attributes變動時,是否需要記錄變動前的屬性值。

2.4、afterAutoResizeMixinInit

    afterAutoResizeMixinInit () {
      const { initConfig, setAppScale } = this
      initConfig()
      setAppScale()
      this.ready = true
    },

組件dom節(jié)點渲染出來后,設(shè)置ready為true,再渲染插槽中的DOM元素。

2.4.1、initConfig

    initConfig () {
      const { dom } = this
      // 當(dāng)前屏幕分辨率
      const { width, height } = screen
      this.allWidth = width
      dom.style.width = `${width}px`
      dom.style.height = `${height}px`
    },

作用:

  • 獲取當(dāng)前設(shè)備屏幕的分辨率
  • 將這個分辨率寬高設(shè)置為組件DOM的寬高

2.4.2、setAppScale

    setAppScale () {
      const { allWidth, dom } = this
      const currentWidth = document.body.clientWidth
      dom.style.transform = `scale(${currentWidth / allWidth})`
    },

它的作用是改變當(dāng)前DOM的縮放比率。

縮放比率 = 當(dāng)前窗口的可視寬度 / 當(dāng)前設(shè)備的屏幕分辨率(寬度)

第3步、beforeDestroy(組件卸載時)

  beforeDestroy () {
    const { unbindDomResizeCallback } = this
    unbindDomResizeCallback()
  }

我們之前對于dom的style屬性和window的resize都做了監(jiān)聽,所以當(dāng)我們組件卸載時這些監(jiān)聽事件也需要移除,如果不移除,那么到其他頁面,做這些操作,監(jiān)聽事件仍然存在,但其實我們已經(jīng)不需要再對他監(jiān)聽了,反而會造成性能浪費。

3.1、unbindDomResizeCallback

    unbindDomResizeCallback () {
      let { domObserver, debounceInitWHFun } = this
      if (!domObserver) return
      domObserver.disconnect()
      domObserver.takeRecords()
      domObserver = null
      window.removeEventListener('resize', debounceInitWHFun)
    }

disconnect方法用來停止觀察。調(diào)用該方法后,DOM 再發(fā)生變動,也不會觸發(fā)觀察器。

takeRecords用來清除變動記錄,即不再處理未處理的變動。該方法返回變動記錄的數(shù)組。

小結(jié)

通過這個源碼閱讀,我們學(xué)習(xí)到了

1、函數(shù)的拆分(每個函數(shù)都只執(zhí)行一個功能)

2、使用對象解構(gòu)賦值,避免濫用this去讀取data和methods中的數(shù)據(jù)和方法

3、使用MutationObserver來監(jiān)聽DOM的變動

其實在閱讀源碼時,也發(fā)現(xiàn)了一個小問題,就是使用mixin,會不利于代碼的閱讀,雖然他可以讓我們復(fù)用一部分代碼邏輯,但也增加了代碼的可閱讀性難度。(它的一些變量和方法的調(diào)用,需要我們多個文件來回尋找)

正好閱讀到一篇文章,vue3的自定義hook可以很好的解決mixin的問題,那么我們就用vue3來重寫下這個組件吧。

以上就是DataV 全屏容器組件源碼解析的詳細(xì)內(nèi)容,更多關(guān)于DataV 全屏容器組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue實現(xiàn)自定義el-table穿梭框功能

    vue實現(xiàn)自定義el-table穿梭框功能

    這篇文章主要介紹了vue實現(xiàn)自定義el-table穿梭框功能,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 解決Vue watch里調(diào)用方法的坑

    解決Vue watch里調(diào)用方法的坑

    這篇文章主要介紹了解決Vue watch里調(diào)用方法的坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Vue監(jiān)聽器簡單使用及注意事項說明

    Vue監(jiān)聽器簡單使用及注意事項說明

    這篇文章主要介紹了Vue監(jiān)聽器簡單使用及注意事項說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Vue 通過自定義指令回顧v-內(nèi)置指令(小結(jié))

    Vue 通過自定義指令回顧v-內(nèi)置指令(小結(jié))

    這篇文章主要介紹了Vue 通過自定義指令回顧v-內(nèi)置指令(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Vue3使用TypeIt實現(xiàn)文字打字機(jī)效果的代碼示例

    Vue3使用TypeIt實現(xiàn)文字打字機(jī)效果的代碼示例

    在現(xiàn)代網(wǎng)頁設(shè)計中,文字打字機(jī)效果是一種非常流行的動畫效果,能夠吸引用戶的注意力并提升用戶體驗,本文將介紹如何在 Vue 3 中使用 TypeIt 庫實現(xiàn)文字打字機(jī)效果,并分享一些實用的技巧和示例,需要的朋友可以參考下
    2025-01-01
  • 深入理解vue-loader如何使用

    深入理解vue-loader如何使用

    本篇文章主要介紹了vue-loader,vue-loader是webpack下loader插件 可以把.vue文件輸出成組件,有興趣的可以了解一下
    2017-06-06
  • 使用Vue3和Vite實現(xiàn)對低版本瀏覽器的兼容

    使用Vue3和Vite實現(xiàn)對低版本瀏覽器的兼容

    在使用Vite和Vue3構(gòu)建的JavaScript項目中,確保對低版本瀏覽器的兼容性是一個重要的考慮因素,以下是一些具體的解決方案和步驟,可以幫助你實現(xiàn)這一目標(biāo),需要的朋友可以參考下
    2024-11-11
  • vue中字典的使用

    vue中字典的使用

    這篇文章主要介紹了vue中字典的使用,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-12-12
  • vue如何實現(xiàn)自定義底部菜單欄

    vue如何實現(xiàn)自定義底部菜單欄

    這篇文章主要介紹了vue如何實現(xiàn)自定義底部菜單欄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • webpack中的optimization配置示例詳解

    webpack中的optimization配置示例詳解

    這篇文章主要介紹了webpack中的optimization配置詳解,主要就是根據(jù)不同的策略來分割打包出來的bundle,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02

最新評論

阳城县| 临安市| 镇平县| 濮阳县| 钟祥市| 新河县| 深州市| 漳州市| 长海县| 昌江| 泸州市| 五常市| 启东市| 抚州市| 梓潼县| 洪江市| 留坝县| 惠来县| 永州市| 乾安县| 尖扎县| 宁国市| 循化| 盐池县| 日土县| 迁西县| 江永县| 鹿泉市| 麻江县| 丰顺县| 吉林省| 广东省| 府谷县| 肇东市| 阳江市| 府谷县| 辽中县| 宝山区| 湖口县| 凤山市| 沁源县|