Rumah  >  Artikel  >  hujung hadapan web  >  Cara vue3 hook membina semula komponen bekas skrin penuh DataV

Cara vue3 hook membina semula komponen bekas skrin penuh DataV

王林
王林ke hadapan
2023-05-16 14:43:061011semak imbas

Pelaksanaan

Buat komponen

fullScreenContainer.vue

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

Sesuaikan cangkuk dan eksport ref mengikat autoBindRef

Fail cangkuk tersuaiuseAutoResize.ts

import { ref } from &#39;vue&#39;;
export function useAutoResize() {
    let domRef = ref<HTMLElement | null>();
    function autoBindRef() {
    }
    return {
        autoBindRef
    }
}

1. Ikat domRef

untuk memastikan elemen dom diperoleh dahulu sebelum logik boleh diteruskan.

Cipta fungsi untuk mengesan dan mendapatkan elemen dom yang betul

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
}

Ikat komponen 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. Inisialisasi

export function useAutoResize() {
    onMounted(() => {
        initDom(domRef.value)
        initConifg(domRef.value)
    })
}

tempoh terpasang secara automatik DOM telah dipasang, jadi elemen DOM perlu diperoleh semasa kitaran ini.

2.1. Mulakan 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 === &#39;function&#39;) setAppScale(dom)
}
2.2. Mulakan peranti
Selepas mendapatkan dom, tetapkan lebar dan ketinggian skrin peranti yang diperolehi kepada dom.
function initConfig(dom:HTMLElement) {
    const { width, height } = screen || {}
    dom.style.width = `${width}px`;
    dom.style.height = `${height}px`;
}

2.3. Tetapkan kesan penskalaan

function setAppScale(dom:HTMLElement){
    const currentWidth = document.body.clientWidth;
    const { width } = screen || {};
    dom.style.transform = `scale(${currentWidth / width})`;
}
Fungsi ini dicetuskan apabila elemen DOM berubah/saiz tetingkap berubah.

3. Pantau/alih keluar acara

Perlu memantau perubahan dalam elemen dom dan saiz tetingkap pada masa yang sama

Pemantauan elemen dom

Di sini kami menggunakan

Untuk memantau perubahan dalam elemen dom

function observerDomResize(dom: HTMLElement, callback: () => void) {
    const observer = new MutationObserver(callback);
    observer.observe(dom, {
        attributes: true,
        attributeFilter: [&#39;style&#39;],
        attributeOldValue: true,
    })
    return observer
}
MutationObserverTetapkan pemantauan semasa kitaran dipasang

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

Tetapi jika kita menulisnya terus seperti ini, ia akan kerap memanggil fungsi handleInitDom, menyebabkan pembaziran prestasi, jadi gunakan Fungsi anti goncang terlebih dahulu membungkus fungsi pemprosesan acara initDom dan kemudian memanggilnya.

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

Jika anda mendengar acara itu, anda mesti mengosongkannya apabila komponen dinyahpasang

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

Atas ialah kandungan terperinci Cara vue3 hook membina semula komponen bekas skrin penuh DataV. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam