Saltar al contenido

Vue JS: cómo obtener el tamaño de la ventana cada vez que cambia

Posterior a consultar especialistas en la materia, programadores de deferentes áreas y maestros hemos dado con la respuesta al dilema y la compartimos en este post.

Solución:

Pon este código dentro de tu componente Vue:

created() 
  window.addEventListener("resize", this.myEventHandler);
,
destroyed() 
  window.removeEventListener("resize", this.myEventHandler);
,
methods: 
  myEventHandler(e) 
    // your code for handling resize...
  

Esto registrará su método Vue en la creación del componente, activará myEventHandler cuando se cambie el tamaño de la ventana del navegador y liberará memoria una vez que se destruya su componente.

Enfoque más simple

https://www.npmjs.com/package/vue-window-size

Avance

import Vue from 'vue';
import VueWindowSize from 'vue-window-size';

Vue.use(VueWindowSize);

Luego accedería normalmente desde sus componentes de esta manera:


Miré el código de esa biblioteca. vue-window-size, y además de la lógica adicional, solo agrega un detector de eventos en el cambio de tamaño de la ventana, y parece que se le puede indicar que rebote. Fuente

El problema crítico para mí es que mi aplicación Vue SPA no emite un evento de cambio de tamaño de ventana cuando cambia una ruta de vue-router que hace que el elemento va de 1000px a 4000px, por lo que me está causando todo tipo de problemas al ver un elemento de lienzo controlado por p5.js para volver a dibujar un fondo de pantalla usando p5.resizeCanvas().

Ahora tengo una solución diferente que implica sondear activamente la altura de compensación de la página.

Lo primero que debe tener en cuenta es la gestión de la memoria de JavaScript, por lo que para evitar pérdidas de memoria, puse setInterval en el created método de ciclo de vida y clearInterval en el beforeDestroy método del ciclo de vida:

created() 
    this.refreshScrollableArea = setInterval(() => 
        const  offsetWidth, offsetHeight  = document.getElementById('app');
        this.offsetWidth = offsetWidth;
        this.offsetHeight = offsetHeight;
    , 100);
,

beforeDestroy() 
    return clearInterval(this.refreshScrollableArea);
,

Como se insinuó en el código anterior, también coloqué un estado inicial:

data() 
    const  offsetWidth, offsetHeight  = document.querySelector('#app');

    return 
        offsetWidth,
        offsetHeight,
        refreshScrollableArea: undefined,
    ;
,

Nota: si estás usando getElementById con algo como this.id (es decir: un elemento que es un hijo en este componente), document.getElementById(this.id) estará indefinido porque los elementos DOM se cargan de afuera hacia adentro, por lo que si ve un error derivado del data creación de instancias, establezca el ancho/alto en 0 inicialmente.

Luego, puse un vigilante offsetHeight para escuchar los cambios de altura y realizar la lógica empresarial:

    watch: 
        offsetHeight() 
            console.log('offsetHeight changed', this.offsetHeight);

            this.state = IS_RESET;
            this.setState(this.sketch);
            return this.draw(this.sketch);
        ,
    ,

Conclusión: probé con performance.now() y:

document.querySelector('#app').offsetHeight 
document.getElementById('app').offsetHeight
document.querySelector('#app').getClientBoundingRect().height

todos se ejecutan en aproximadamente la misma cantidad de tiempo: 0.2ms, por lo que el código anterior cuesta alrededor de 0,2 ms cada 100 ms. Actualmente encuentro eso razonable en mi aplicación, incluso después de ajustar los clientes lentos que operan un orden de magnitud más lento que mi máquina local.

Esta es la lógica de prueba para su propia I+D:

const t0 = performance.now();
const  offsetWidth, offsetHeight  = document.getElementById('app');
const t1 = performance.now();

console.log('execution time:', (t1 - t0), 'ms');

Prima: si tiene algún problema de rendimiento debido a un tiempo de ejecución prolongado en su setInterval función, intente envolverlo en un marco de animación de doble solicitud:

created() 
    this.refreshScrollableArea = setInterval(() => 
        return requestAnimationFrame(() => requestAnimationFrame(() => 
            const  offsetWidth, offsetHeight  = document.getElementById(this.id);
            this.offsetWidth = offsetWidth;
            this.offsetHeight = offsetHeight;
        ));
    , 100);
,

requestAnimationFrame en sí mismo una persona debe investigar. Lo dejaré fuera del alcance de esta respuesta.

Para terminar, otra idea que investigué más tarde, pero que no estoy usando, es usar un método recursivo setTimeout función con un tiempo de espera dinámico (es decir, un tiempo de espera que decae después de que se carga la página); sin embargo, si considera la técnica recursiva setTimeout, tenga en cuenta la longitud de la pila de llamadas/cola de funciones y la optimización de las llamadas finales. El tamaño de la pila podría escaparse de ti.

Acuérdate de que tienes concesión de reseñar tu experiencia si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *