Maison >interface Web >Voir.js >Comment le hook vue3 reconstruit le composant conteneur plein écran de DataV

Comment le hook vue3 reconstruit le composant conteneur plein écran de DataV

王林
王林avant
2023-05-16 14:43:061064parcourir

Implémentation

Créer un composant

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>

Personnalisez un hook et exportez une référence de liaison autoBindRef

fichier de hook personnalisé

utilisezAutoResize.ts

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

1. récupère le premier élément DOM , la logique peut continuer à baisser.

Créez une fonction pour détecter et obtenir l'élément dom correct

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
}

Lier automatiquement le composant 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 Pendant la période d'initialisation

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

montée, le dom a été monté, il est donc nécessaire d'obtenir l'élément dom. durant ce cycle.

2.1. Initialiser le 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. Initialiser l'appareil
Après avoir obtenu le dom, définissez la largeur et la hauteur de la résolution de l'écran de l'appareil obtenu sur le dom.
function initConfig(dom:HTMLElement) {
    const { width, height } = screen || {}
    dom.style.width = `${width}px`;
    dom.style.height = `${height}px`;
}

2.3. Définir l'effet de zoom

function setAppScale(dom:HTMLElement){
    const currentWidth = document.body.clientWidth;
    const { width } = screen || {};
    dom.style.transform = `scale(${currentWidth / width})`;
}
Cette fonction est déclenchée lorsque l'élément dom change/la taille de la fenêtre change.

3. Événements d'écoute/suppression

Besoin de surveiller les changements dans les éléments dom et la taille des fenêtres en même temps

Surveillance des éléments dom

Ici, nous utilisons

pour surveiller les changements dans les éléments 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
}
MutationObserverDéfinir la surveillance pendant le cycle monté

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);
    })
}

Mais si nous l'écrivons directement comme ceci, il appellera fréquemment la fonction handleInitDom, provoquant un gaspillage de performances, utilisez donc la fonction anti-shake pour envelopper la fonction de traitement d'événements handleInitDom avant de l'appeler.

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);
          }
        );
    })
}

Si vous écoutez l'événement, vous devez l'effacer lorsque le composant est désinstallé

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer