中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

vue3?hook如何重構DataV的全屏容器組件

發布時間:2023-05-16 16:43:27 來源:億速云 閱讀:133 作者:iii 欄目:編程語言

今天小編給大家分享一下vue3 hook如何重構DataV的全屏容器組件的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

實現

創建組件

fullScreenContainer.vue

<template>
  <div id="dv-full-screen-container" :ref="autoBindRef">
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
import { useAutoResize } from '@/hooks/useAutoResize'
const { autoBindRef } = useAutoResize()
</script>

自定義一個hook,導出一個autoBindRef綁定ref

自定義hook文件

useAutoResize.ts

import { ref } from 'vue';
export function useAutoResize() {
    let domRef = ref<HTMLElement | null>();
    function autoBindRef() {
    }
    return {
        autoBindRef
    }
}
1、綁定domRef

確保先獲取到dom元素,邏輯才可以繼續往下走。

創建一個函數,用于檢測獲取正確的dom元素

function getRefDom(ref: HTMLElement | ComponentPublicInstance): HTMLElement | null {
  // ref指向dom,則返回ref
  // isElement檢查指定的值是否為DOM元素
  if (isElement(ref)) {
    return ref as HTMLElement
  }
  // 若ref指向組件實例,通過$el獲取dom元素
  if (isElement((ref as ComponentPublicInstance).$el)) {
    return (ref as ComponentPublicInstance).$el
  }
  return null
}

自動綁定組件domRef

export function useAutoResize() {
    let domRef = ref<HTMLElement | null>();
    const autoBindRef = once((ref: HTMLElement | ComponentPublicInstance) =>  {
        const  dom = getRefDom(ref);
        if(!dom) {
            console.warn("綁定組件domRef失敗!")
            return;
        }
        domRef.value = dom;
    })
    return {
        autoBindRef
    }
}
2、初始化
export function useAutoResize() {
    onMounted(() => {
        initDom(domRef.value)
        initConifg(domRef.value)
    })
}

mounted時期,dom都已掛載完畢,故需在此周期獲取dom元素。

2.1、初始化dom
function initDom(dom:HTMLElement) {
    const { clientWidth = 0, clientHeight = 0 } = dom || {}
    if(!dom) {
        console.warn("獲取dom節點失敗,組件渲染可能異常!")
        return
    } else if(!clientWidth || !clientHeight) {
        console.warn("組件寬度或高度為0px,可能會出現渲染異常!")
        return
    }
    // 設置縮放比例
    if(typeof setAppSacle === 'function') setAppScale(dom)
}
2.2、初始化設備

獲取到dom后,將獲取到的設備屏幕分辨率寬高設置給dom。

function initConfig(dom:HTMLElement) {
    const { width, height } = screen || {}
    dom.style.width = `${width}px`;
    dom.style.height = `${height}px`;
}
2.3、設置縮放效果
function setAppScale(dom:HTMLElement){
    const currentWidth = document.body.clientWidth;
    const { width } = screen || {};
    dom.style.transform = `scale(${currentWidth / width})`;
}

當dom元素改變/窗口大小變化時,觸發這個函數。

3、監聽/移除事件

需要同時對dom元素和窗口大小的變化監聽

dom元素監聽

這里我們使用MutationObserver來對dom元素的變化來監聽

function observerDomResize(dom: HTMLElement, callback: () => void) {
    const observer = new MutationObserver(callback);
    observer.observe(dom, {
        attributes: true,
        attributeFilter: ['style'],
        attributeOldValue: true,
    })
    return observer
}

在mounted周期內設置監聽

export function useAutoResize() {
    const handleInitDom = () => {
        initDom(domRef.value)
    }
    onMounted(() => {
        initDom(domRef.value)
        initConifg(domRef.value)
        observerDomResize(domRef.value, handleInitDom)
        window.removeEventListener('resize', handleInitDom);
    })
}

但是如果我們直接這樣寫,他就會頻繁調用handleInitDom函數,造成性能浪費,所以使用防抖函數先包裝一下事件處理函數handleInitDom再調用。

export function useAutoResize() {
    const domSizeEffectDisposer: (() => void)[] = [];
    const debounceInitDomFun = debounce(handleInitDom, 300)
    onMounted(() => {
        initDom(domRef.value)
        initConifg(domRef.value)
        observerDomResize(domRef.value, debounceInitDomFun)
        window.removeEventListener('resize', debounceInitDomFun);
        domSizeEffectDisposer.push(
          () => {
            if (!observer) return
            observer.disconnect();
            observer.takeRecords();
            observer = null;
          },
          () => {
            window.removeEventListener('resize', debounceInitDomFun);
          }
        );
    })
}

監聽了事件,那么在組件卸載時就要清除它

onUnmounted(() => {
    domSizeEffectDisposer.forEach(disposer => disposer())
  })

以上就是“vue3 hook如何重構DataV的全屏容器組件”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

大余县| 芜湖市| 常山县| 新巴尔虎左旗| 通山县| 泗阳县| 武定县| 临沭县| 措勤县| 乌鲁木齐县| 高唐县| 南昌市| 滁州市| 双鸭山市| 兴国县| 明水县| 仪征市| 正镶白旗| 伊金霍洛旗| 霍林郭勒市| 闻喜县| 东乡族自治县| 手游| 连平县| 买车| 临桂县| 博湖县| 连州市| 普陀区| 临沂市| 芦山县| 汽车| 黑河市| 平度市| 会同县| 岳普湖县| 新巴尔虎左旗| 安塞县| 镇雄县| 德昌县| 扶绥县|