Vue JS - 如何在窗口大小发生变化时获取窗口大小

时间:2018-03-20 09:44:15

标签: javascript html vue.js

我是vuejs的新手,但每当我试图获得窗口大小时    调整它的大小,以便我可以将它与我的函数的某个值进行比较    需要根据屏幕尺寸进行申请。我也试过用    看房产,但不知道如何处理它,这可能是它没有工作的原因

  methods: {

    elem() {
     this.size = window.innerWidth;
     return this.size;
   },
  mounted() {
    if (this.elem < 767){ //some code }
   }

4 个答案:

答案 0 :(得分:9)

将此代码放入Vue组件中:

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

这将在事件上注册vue方法,为您提供完整的Vue对象以及事件对象,并在组件destroy(可用内存)上将其删除。

答案 1 :(得分:5)

最简单的方法

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

预览

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

Vue.use(VueWindowSize);

然后,您通常可以从组件中像这样访问它:

<template>
  <div>
    <p>window width: {{ windowWidth }}</p>
    <p>window height: {{ windowHeight }}</p>
  </div>
</template>

答案 2 :(得分:2)

我查看了该库vue-window-size的代码,除了附加的逻辑外,它只是在窗口调整大小上添加了一个事件侦听器,看起来可以指示其去抖动。 Source

对我来说,关键问题在于,当vue-router路由发生变化,导致<html>元素从1000px变为4000px时,我的Vue SPA应用程序不会发出窗口调整大小事件,这导致了我各种在观看由p5.js控制的画布元素以使用p5.resizeCanvas()重绘墙纸时出现问题。

我现在有一个不同的解决方案,它涉及主动轮询页面的偏移高度。

首先要注意的是JavaScript内存管理,因此为了避免内存泄漏,我将setInterval放在created生命周期方法中,并将clearInterval放在beforeDestroy生命周期方法中:

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

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

如上述代码所示,我还放置了一些初始状态:

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

    return {
        offsetWidth,
        offsetHeight,
        refreshScrollableArea: undefined,
    };
},

注意:如果您将getElementByIdthis.id之类的东西一起使用(即,该元素是此组件中的子元素),则document.getElementById(this.id)将是未定义,因为DOM元素从内到外加载,因此,如果您看到由data实例化引起的错误,请首先将width / height设置为0

然后,我在offsetHeight上放置了一个观察者,以监听高度变化并执行业务逻辑:

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

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

结论:我用performance.now()和:

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

全部执行的时间大致相同:0.2ms,因此上述代码每100ms花费约0.2ms。我目前在我的应用程序中发现这是合理的,包括在我调整了慢于运行速度比本地计算机慢一个数量级的客户端之后。

这是您自己的研发的测试逻辑:

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

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

奖金::如果由于setInterval函数的执行时间较长而导致性能问题,请尝试将其包装在double-requestAnimationFrame中:

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

requestAnimationFrame本身应该由人进行研究。我将其排除在此答案范围之外。

最后,我后来研究但未使用的另一个想法是使用具有动态超时的递归setTimeout函数(即:页面加载后衰减的超时);但是,如果考虑使用递归setTimeout技术,请注意调用堆栈/函数队列的长度和尾部调用的优化。堆栈大小可能会耗尽您的精力。

答案 3 :(得分:1)

您可以随时随地使用此

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