今天小編給大家分享一下vue3 hook如何重構(gòu)DataV的全屏容器組件的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的沽源網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
fullScreenContainer.vue
自定義一個hook,導(dǎo)出一個autoBindRef綁定ref
useAutoResize.ts
import { ref } from 'vue'; export function useAutoResize() { let domRef = ref(); function autoBindRef() { } return { autoBindRef } }
確保先獲取到dom元素,邏輯才可以繼續(xù)往下走。
創(chuàng)建一個函數(shù),用于檢測獲取正確的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(); const autoBindRef = once((ref: HTMLElement | ComponentPublicInstance) => { const dom = getRefDom(ref); if(!dom) { console.warn("綁定組件domRef失??!") return; } domRef.value = dom; }) return { autoBindRef } }
export function useAutoResize() { onMounted(() => { initDom(domRef.value) initConifg(domRef.value) }) }
mounted時期,dom都已掛載完畢,故需在此周期獲取dom元素。
function initDom(dom:HTMLElement) { const { clientWidth = 0, clientHeight = 0 } = dom || {} if(!dom) { console.warn("獲取dom節(jié)點(diǎn)失敗,組件渲染可能異常!") return } else if(!clientWidth || !clientHeight) { console.warn("組件寬度或高度為0px,可能會出現(xiàn)渲染異常!") return } // 設(shè)置縮放比例 if(typeof setAppSacle === 'function') setAppScale(dom) }
獲取到dom后,將獲取到的設(shè)備屏幕分辨率寬高設(shè)置給dom。
function initConfig(dom:HTMLElement) { const { width, height } = screen || {} dom.style.width = `${width}px`; dom.style.height = `${height}px`; }
function setAppScale(dom:HTMLElement){ const currentWidth = document.body.clientWidth; const { width } = screen || {}; dom.style.transform = `scale(${currentWidth / width})`; }
當(dāng)dom元素改變/窗口大小變化時,觸發(fā)這個函數(shù)。
需要同時對dom元素和窗口大小的變化監(jiān)聽
dom元素監(jiān)聽
這里我們使用MutationObserver
來對dom元素的變化來監(jiān)聽
function observerDomResize(dom: HTMLElement, callback: () => void) { const observer = new MutationObserver(callback); observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true, }) return observer }
在mounted周期內(nèi)設(shè)置監(jiān)聽
export function useAutoResize() { const handleInitDom = () => { initDom(domRef.value) } onMounted(() => { initDom(domRef.value) initConifg(domRef.value) observerDomResize(domRef.value, handleInitDom) window.removeEventListener('resize', handleInitDom); }) }
但是如果我們直接這樣寫,他就會頻繁調(diào)用handleInitDom函數(shù),造成性能浪費(fèi),所以使用防抖函數(shù)先包裝一下事件處理函數(shù)handleInitDom再調(diào)用。
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); } ); }) }
監(jiān)聽了事件,那么在組件卸載時就要清除它
onUnmounted(() => { domSizeEffectDisposer.forEach(disposer => disposer()) })
以上就是“vue3 hook如何重構(gòu)DataV的全屏容器組件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。