溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

DataV全屏容器組件源碼分析

發(fā)布時間:2023-04-07 15:41:36 來源:億速云 閱讀:206 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“DataV全屏容器組件源碼分析”,在日常操作中,相信很多人在DataV全屏容器組件源碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”DataV全屏容器組件源碼分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    引言

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

    源碼閱讀(vue2版本)

    它的源碼位置

    DataV全屏容器組件源碼分析

    看下它的DOM結構,很簡單

    <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進行操作)

    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()
        },
    }

    這其中調用了幾個函數(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已經渲染好了,再去執(zhí)行其他函數(shù)。

    2.1.1、onResize

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

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

    2.2、getDebounceInitWHFun

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

    獲取一個經過防抖的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進行監(jiān)聽。

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

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

    • dom的樣式改變時觸發(fā)

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

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

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

    封裝一個observerDomResize函數(shù)來對dom的style屬性變化進行監(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é)點渲染出來后,設置ready為true,再渲染插槽中的DOM元素。

    2.4.1、initConfig

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

    作用:

    • 獲取當前設備屏幕的分辨率

    • 將這個分辨率寬高設置為組件DOM的寬高

    2.4.2、setAppScale

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

    它的作用是改變當前DOM的縮放比率。

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

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

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

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

    3.1、unbindDomResizeCallback

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

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

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

    到此,關于“DataV全屏容器組件源碼分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

    AI