Maison > interface Web > Voir.js > le corps du texte

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

王林
Libérer: 2023-05-16 14:43:06
avant
1052 Les gens l'ont consulté

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>
Copier après la connexion

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
    }
}
Copier après la connexion

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
}
Copier après la connexion

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
    }
}
Copier après la connexion

2 Pendant la période d'initialisation

export function useAutoResize() {
    onMounted(() => {
        initDom(domRef.value)
        initConifg(domRef.value)
    })
}
Copier après la connexion

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)
}
Copier après la connexion
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`;
}
Copier après la connexion

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})`;
}
Copier après la connexion
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
}
Copier après la connexion
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);
    })
}
Copier après la connexion

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);
          }
        );
    })
}
Copier après la connexion

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

onUnmounted(() => {
    domSizeEffectDisposer.forEach(disposer => disposer())
  })
Copier après la connexion

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!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal