Ich bin neu bei vuejs, aber ich habe versucht, die Fenstergröße zu erhalten, wenn ich die Größe ändere, damit ich sie mit einem Wert für eine Funktion vergleichen kann, die ich je nach Bildschirmgröße anwenden muss. Ich habe auch versucht, die Watch-Eigenschaft zu verwenden, bin mir aber nicht sicher, wie ich damit umgehen soll, deshalb hat es wahrscheinlich nicht funktioniert
methods: {
elem() {
this.size = window.innerWidth;
return this.size;
},
mounted() {
if (this.elem < 767){ //some code }
}
Fügen Sie diesen Code in Ihre Vue-Komponente ein:
created() {
window.addEventListener("resize", this.myEventHandler);
},
destroyed() {
window.removeEventListener("resize", this.myEventHandler);
},
methods: {
myEventHandler(e) {
// your code for handling resize...
}
}
Dies registriert Ihre Vue-Methode bei der Komponentenerstellung, löst myEventHandler aus, wenn die Größe des Browserfensters geändert wird, und gibt Speicher frei, sobald Ihre Komponente zerstört ist.
Einfachster Ansatz
https://www.npmjs.com/package/vue-window-size
Vorschau
import Vue from 'vue';
import VueWindowSize from 'vue-window-size';
Vue.use(VueWindowSize);
Sie würden dann normalerweise von Ihren Komponenten wie folgt darauf zugreifen:
<template>
<div>
<p>window width: {{ windowWidth }}</p>
<p>window height: {{ windowHeight }}</p>
</div>
</template>
Ich habe mir den Code dieser Bibliothek angesehen vue-window-size
und neben der zusätzlichen Logik fügt es nur einen Ereignis-Listener bei der Größenänderung des Fensters hinzu, und es sieht so aus, als könnte es angewiesen werden, zu entprellen. Quelle
Das kritische Problem für mich ist, dass meine Vue SPA-App kein Ereignis zur Größenänderung des Fensters ausgibt, wenn sich eine Vue-Router-Route ändert, die das macht <html>
Element von 1000px auf 4000px gehen, also verursacht es mir alle möglichen Probleme, wenn ich ein von p5.js gesteuertes Canvas-Element anschaue, um ein Hintergrundbild neu zu zeichnen p5.resizeCanvas()
.
Ich habe jetzt eine andere Lösung, bei der die Offset-Höhe der Seite aktiv abgefragt wird.
Das erste, was Sie beachten sollten, ist die JavaScript-Speicherverwaltung. Um Speicherlecks zu vermeiden, habe ich setInterval in die created
lifecycle-Methode und clearInterval in der beforeDestroy
Lebenszyklusmethode:
created() {
this.refreshScrollableArea = setInterval(() => {
const { offsetWidth, offsetHeight } = document.getElementById('app');
this.offsetWidth = offsetWidth;
this.offsetHeight = offsetHeight;
}, 100);
},
beforeDestroy() {
return clearInterval(this.refreshScrollableArea);
},
Wie im obigen Code angedeutet, habe ich auch einen Anfangszustand platziert:
data() {
const { offsetWidth, offsetHeight } = document.querySelector('#app');
return {
offsetWidth,
offsetHeight,
refreshScrollableArea: undefined,
};
},
Notiz: wenn Sie verwenden getElementById
mit sowas this.id
(dh: ein Element, das ein untergeordnetes Element in dieser Komponente ist), document.getElementById(this.id)
ist undefiniert, da DOM-Elemente von außen nach innen geladen werden. Wenn Sie also einen Fehler sehen, der von der data
Instanziierung, setzen Sie die Breite/Höhe auf 0
anfänglich.
Dann schalte ich einen Wächter ein offsetHeight
um auf Höhenänderungen zu hören und Geschäftslogik auszuführen:
watch: {
offsetHeight() {
console.log('offsetHeight changed', this.offsetHeight);
this.state = IS_RESET;
this.setState(this.sketch);
return this.draw(this.sketch);
},
},
Fazit: Ich habe mit getestet performance.now()
und:
document.querySelector('#app').offsetHeight
document.getElementById('app').offsetHeight
document.querySelector('#app').getClientBoundingRect().height
alle werden in etwa der gleichen Zeit ausgeführt: 0.2ms
, also kostet der obige Code etwa 0,2 ms alle 100 ms. Ich finde das derzeit in meiner App angemessen, auch nachdem ich mich auf langsame Clients eingestellt habe, die eine Größenordnung langsamer als meine lokale Maschine arbeiten.
Hier ist die Testlogik für Ihre eigene F&E:
const t0 = performance.now();
const { offsetWidth, offsetHeight } = document.getElementById('app');
const t1 = performance.now();
console.log('execution time:', (t1 - t0), 'ms');
Bonus: wenn Sie Leistungsprobleme aufgrund einer langen Ausführungszeit auf Ihrer erhalten setInterval
Funktion, versuchen Sie, sie in einen Double-RequestAnimationFrame zu packen:
created() {
this.refreshScrollableArea = setInterval(() => {
return requestAnimationFrame(() => requestAnimationFrame(() => {
const { offsetWidth, offsetHeight } = document.getElementById(this.id);
this.offsetWidth = offsetWidth;
this.offsetHeight = offsetHeight;
}));
}, 100);
},
requestAnimationFrame
selbst sollte eine Person forschen. Ich werde es aus dem Rahmen dieser Antwort herauslassen.
Abschließend eine andere Idee, die ich später recherchiert habe, aber nicht verwende, ist die Verwendung einer Rekursion setTimeout
Funktion mit einem dynamischen Timeout darauf (dh: ein Timeout, das abfällt, nachdem die Seite geladen wurde); Wenn Sie jedoch die rekursive setTimeout-Technik in Betracht ziehen, achten Sie auf die Callstack-/Funktionswarteschlangenlänge und die Tail-Call-Optimierung. Die Stapelgröße könnte Ihnen davonlaufen.
Sie können dies jederzeit und überall verwenden
methods: {
//define below method first.
winWidth: function () {
setInterval(() => {
var w = window.innerWidth;
if (w < 768) {
this.clientsTestimonialsPages = 1
} else if (w < 960) {
this.clientsTestimonialsPages = 2
} else if (w < 1200) {
this.clientsTestimonialsPages = 3
} else {
this.clientsTestimonialsPages = 4
}
}, 100);
}
},
mounted() {
//callback once mounted
this.winWidth()
}
Für Vue3 können Sie den folgenden Code verwenden:
mounted() {
window.addEventListener("resize", this.myEventHandler);
},
unmounted() {
window.removeEventListener("resize", this.myEventHandler);
},
methods: {
myEventHandler(e) {
// your code for handling resize...
}
}
Destroyed und BeforeDestroyed sind in Vue3 veraltet, daher möchten Sie vielleicht BeforeUnmount und Unmount verwenden
document.addEventListener('resize', <yourfunction>);
? Ich habe keine Ahnung vonvue
.– Ausdrücken von x
20. März 2018 um 9:46 Uhr
Siehe stackoverflow.com/a/49381187/906113
– Str
20. März 2018 um 10:03 Uhr