Wie kann ich sich ändernde Fenstergrößen in Vue überwachen?

Lesezeit: 6 Minuten

Benutzeravatar von bbsimonbb
bbsimonbb

In meiner mobilen Web-App mit Vue möchte ich meine Fußzeile ausblenden, wenn die Soft-Tastatur erscheint. Ich habe also eine kleine Funktion, um das Verhältnis von Fensterhöhe zu Fensterbreite zu testen …

showFooter(){
    return h / w > 1.2 || h > 560;
}

…und ich deklariere window.innerHeight/window.innerWidth in meinen Daten.

    data: { h: window.innerHeight, w: window.innerWidth }

Das Problem ist, dass meine h-Eigenschaft nicht den neuen Wert erhält, wenn sich window.innerHeight ändert. Wie kann ich window.innerHeight beobachten?

  • Könnte man es nicht anhand der Fensterbreite/-höhe anhand des Eingabe-/Auswahl-/Textbereichsfokus tun?

    – Dan Gamble

    10. November 2017 um 9:33 Uhr

samayos Benutzeravatar
Samayo

Um die aktuelle Fensterhöhe Ihres Browsers bei Änderungen zu ermitteln, verwenden Sie dieses Skript:

new Vue({
  el: '#app',
  data() {
    return {
      windowHeight: window.innerHeight
    }
  },

  mounted() {
    this.$nextTick(() => {
      window.addEventListener('resize', this.onResize);
    })
  },

  beforeDestroy() { 
    window.removeEventListener('resize', this.onResize); 
  },

  methods: {  
    onResize() {
      this.windowHeight = window.innerHeight
    }
  }
});

Um die Informationen anzuzeigen, verwenden Sie:

<div id="app">
 Current height: {{ windowHeight }}
</div>

  • Nur eine Erinnerung daran, so etwas zu verwenden beforeDestroy() { window.removeEventListener('scroll', this.onScrollFunction); } Ich betone die Verwendung noch mehr, wenn es sich um ein SPA handelt.

    – Marlon Barcarol

    10. Juli 2018 um 17:25 Uhr


  • @MarlonBarcarol warum ist das notwendig?

    – Chris Jung

    18. September 2019 um 8:14

  • Dies ist notwendig, da beim Wechseln zwischen Komponenten Hunderte oder Tausende von Ereignis-Listenern registriert sind, die Speicher verbrauchen und den Browser verlangsamen. Wenn eine Komponente entfernt (zerstört) wird, möchten Sie stattdessen alle Ereignis-Listener entfernen, die sich auf diese Komponente beziehen, da sie nicht mehr benötigt werden.

    – John Mellor

    19. Okt. 2019 um 4:34

  • Entscheidend ist, dass Sie dies tun müssen, weil der Zuhörer dabei ist Fensternicht die Komponente, die zerstört wird.

    – Darvanen

    18. Dezember 2019 um 21:41 Uhr

  • Warum ist $nextTick hier notwendig?

    – Dylan Landry

    1. Februar 2021 um 16:46 Uhr

Benutzeravatar von kshksdrt
kshksdrt

VUE 2.7 und höher

In Vue 2.7+ können Sie ein Composable erstellen, das eine reaktive Breite und einen Haltepunktnamen zurückgibt.

import { computed, onMounted, onUnmounted, ref } from "vue"

export const useBreakpoints = () => {
  let windowWidth = ref(window.innerWidth)

  const onWidthChange = () => windowWidth.value = window.innerWidth
  onMounted(() => window.addEventListener('resize', onWidthChange))
  onUnmounted(() => window.removeEventListener('resize', onWidthChange))
  
  const type = computed(() => {
    if (windowWidth.value < 550) return 'xs'
    if (windowWidth.value >= 550 && windowWidth.value < 1200) return 'md'
    else return 'lg' // Fires when windowWidth.value >= 1200
  })

  const width = computed(() => windowWidth.value)

  return { width, type }
}

Sie können es in der Einrichtungsmethode Ihrer Komponenten verwenden.

const { width, type } = useBreakpoints()

Kurzer Tipp: Aus Leistungsgründen sollte dies am besten nur einmal in einer App verwendet werden.

  • Erstellen Sie ein kleines Plugin und fügen Sie den Wert zur Vue-Instanz hinzu, genau wie Vuetify.

  • Oder verwenden Sie „provide and inject“.

  • Oder binden Sie sie in Ihre globale State-Management-Lösung ein.

  • Das hat bei mir nicht funktioniert – ich habe die folgende Fehlermeldung erhalten: 10:25 error Expected to return a value in computed function vue/return-in-computed-property

    – DmnkVD

    3. Dezember 2021 um 19:38 Uhr


  • Es muss eine Eslint-Regel sein. Eslint kann nicht ableiten, dass es hier immer einen Rückgabewert geben wird. Eslint ist für diese Fälle berüchtigt. Sie können für diese Zeile/Datei bedenkenlos ein „eslint ignorieren“ hinzufügen.

    – kshksdrt

    4. Dezember 2021 um 9:28

  • Vielen Dank für die Klarstellung! Gibt es auch eine Möglichkeit, diese Dienstprogrammfunktion in eine Komponente zu importieren, die nicht mit setup() geschrieben wurde (verwendet Optionen)?

    – DmnkVD

    4. Dezember 2021 um 10:34


  • Es muss in einer Setup-Methode verwendet werden. Sie könnten eine neue Setup-Methode erstellen, die Funktion aufrufen und zurückgeben. Es ist ganz normal, sowohl die Kompositions-API als auch die Options-API in derselben Komponente zu verwenden.

    – kshksdrt

    5. Dezember 2021 um 8:54

  • Hallo, ich versuche, dies in meinem Projekt zum Laufen zu bringen und habe ein paar Probleme damit, die Verwendung dieses Plugins zu verstehen. Eigentlich suche ich nur nach der Breite, aber ich habe den gesamten Code verwendet, den Sie geschrieben haben. Ich habe den obersten Teil des Codes in a ausgelagert window-width.ts Datei und versuche, in einer anderen Komponente darauf zuzugreifen. Ich verstehe die in Ihrem Fall verwendete Destrukturierung nicht wirklich const { width, type } = useBreakpoints() Ich bin noch ein bisschen neu in Vue und der Verwendung von Plugins, also ist es vielleicht nur ein grundlegendes Missverständnis, aber wenn Sie irgendwelche Ideen haben, wäre ich wirklich dankbar!

    – LovelyAndy

    15. Dezember 2021 um 15:59 Uhr

Benutzeravatar von cub33
cub33

Die obige Antwort hat bei mir nicht funktioniert. Stattdessen habe ich Folgendes verwendet:

mounted() {
  window.addEventListener('resize', () => {
    this.windowHeight = window.innerHeight
  })
}

  • Irgendetwas stimmt mit deinen Klammern nicht. window.addEventListener('resize', () => { this.windowHeight = window.innerHeight });

    – mvandillen

    24. Juni 2020 um 8:33

Wer Vuetify bereits nutzt, kann einfach zuschauen this.$vuetify.breakpoint.width oder this.$vuetify.breakpoint.height für Änderungen in den Abmessungen des Ansichtsfensters.

Vuetify-Breakpoint-Dokumente

Shulz' Benutzer-Avatar
Schulz

Das ist wahrscheinlich wirklich zu spät, aber wenn Sie einen viel einfacheren Ansatz wünschen, können Sie die NPM-Installation durchführen https://www.npmjs.com/package/vue-window-size
Und import windowWidth from 'vue-window-size';

Oder dies mit der Kompositions-API

    setup() {
        const windowSize = ref(window.innerWidth)
        onMounted(() => {
            window.addEventListener('resize', () => {windowSize.value = window.innerWidth} )
        })
        onUnmounted(() => {
            window.removeEventListener('resize', () => {windowSize.value = window.innerWidth})
        })
        return { 
            windowSize
        }
    }

  • Niemals zu spät!

    – bbsimonbb

    10. Juni 2021 um 7:35 Uhr

  • Sie müssen eine Funktion erstellen und diese in Listenern verwenden. In Ihrem Beispiel fügen Sie Listener zu unterschiedlichen Funktionen hinzu und entfernen sie. Das Entfernen des Ereignisses funktioniert also nicht. window.addEventListener('resize', func), window.removeEventListener('resize', func)

    – n4ks

    22. Februar 2022 um 0:38


Kaloyan Nikolovs Benutzeravatar
Kaloyan Nikolov

Meine Antwort kommt vielleicht zu spät, aber keines der oben genannten Dinge hat bei mir funktioniert. Hier ist also, was ich zu diesem Thema gefunden habe! 🙂 🙂

https://codepen.io/sethdavis512/pen/EvNKWw

HTML:

<div id="app">
    <section class="section has-text-centered">
        <h1 class="title is-1">
            Your Window
        </h1>
        <h3 class="title is-3">
            Width: {{ window.width }} px<br/>
            Height: {{ window.height }} px
        </h3>
        <p class="has-text-white">
            &uarr;<br/>
            &larr; resize window &rarr;<br/>
            &darr;
        </p>
    </section>
</div>

CSS:

$top-color: yellow;
$bottom-color: tomato;

html, body, #app, section.section {
  height: 100%;
}

body {
    background: -webkit-linear-gradient($top-color, $bottom-color);
    background: -o-linear-gradient($top-color, $bottom-color);
    background: -moz-linear-gradient($top-color, $bottom-color);
    background: linear-gradient($top-color, $bottom-color);
}

section.section {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
}

.title {
    color: white;
}

JS:

new Vue({
    el: '#app',
    data: {
        window: {
            width: 0,
            height: 0
        }
    },
    created() {
        window.addEventListener('resize', this.handleResize);
        this.handleResize();
    },
    destroyed() {
        window.removeEventListener('resize', this.handleResize);
    },
    methods: {
        handleResize() {
            this.window.width = window.innerWidth;
            this.window.height = window.innerHeight;
        }
    }
});

  • Niemals zu spät!

    – bbsimonbb

    10. Juni 2021 um 7:35 Uhr

  • Sie müssen eine Funktion erstellen und diese in Listenern verwenden. In Ihrem Beispiel fügen Sie Listener zu unterschiedlichen Funktionen hinzu und entfernen sie. Das Entfernen des Ereignisses funktioniert also nicht. window.addEventListener('resize', func), window.removeEventListener('resize', func)

    – n4ks

    22. Februar 2022 um 0:38


1453950cookie-checkWie kann ich sich ändernde Fenstergrößen in Vue überwachen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy