【问题标题】:How can I use window size in Vue? (How do I detect the soft keyboard?)如何在 Vue 中使用窗口大小? (如何检测软键盘?)
【发布时间】:2018-04-23 11:24:55
【问题描述】:

在我的带有 Vue 的移动网络应用程序中,我想在软键盘弹出时隐藏我的页脚。所以我有一个小功能来测试窗口高度与窗口宽度的比率......

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

...我在我的数据中声明了 window.innerHeight/window.innerWidth。

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

问题是,当 window.innerHeight 改变时,我的 h 属性没有得到新的值。如何观看 window.innerHeight ?

【问题讨论】:

  • 你不能在输入/选择/文本区域焦点上做而不是根据窗口宽度/高度来做吗?

标签: vue.js


【解决方案1】:

我确信有更好的方法可以做到这一点,但在我想出一些方法之前,这个方法对你有用:

基本上你只需要一个数据道具和一个观察者就可以做到这一点。

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

    watch: {
        windowHeight(newHeight, oldHeight) {
            this.txt = `it changed to ${newHeight} from ${oldHeight}`;
        }
    },

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

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

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

这将输出更改

<div id="app">
    <br> Window height: {{ windowHeight }} <br/>
    {{ txt }}
</div>

【讨论】:

  • 只是提醒您使用beforeDestroy() { window.removeEventListener('scroll', this.onScrollFunction); } 之类的东西,当它是 SPA 时,我会更加强调使用它。
  • @MarlonBarcarol 为什么有必要这样做?
  • 这是必要的,因为当您在组件之间移动时,您最终会注册 100 或 1000 多个事件侦听器,这会占用内存并减慢浏览器的速度。相反,当一个组件被移除(销毁)时,您希望移除与该组件相关的任何事件侦听器,因为它不再需要。
  • 至关重要 - 您需要这样做,因为侦听器位于 窗口 上,而不是被销毁的组件。
  • 这里为什么需要$nextTick
【解决方案2】:

上面的答案对我不起作用。相反,我使用了:

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

【讨论】:

  • 你的括号有些不对劲。 window.addEventListener('resize', () =&gt; { this.windowHeight = window.innerHeight });
【解决方案3】:

对于那些已经在使用 Vuetify 的人,您可以观看 this.$vuetify.breakpoint.widththis.$vuetify.breakpoint.height 以了解视口尺寸的变化。

Vuetify breakpoint docs

【讨论】:

  • 正是我想要的。您也可以使用xs,sm,md 而不是检查宽度(检查链接的文档)
【解决方案4】:

VUE 3

在 Vue 3 中,您可以创建一个可以返回响应式宽度和断点名称值的函数。您可以轻松地跨多个组件重用该功能。

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

export default function () {
  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'
    if (windowWidth.value >= 1200) return 'lg'
    return null; // This is an unreachable line, simply to keep eslint happy.
  })

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

  return { width, type }
}

您可以在您的 vue 3 组件的 setup 方法中使用它,如下所示。

const { width, type } = useBreakpoints()

快速提示:尽管文档事件侦听器是世界上最优化的东西,但出于性能原因,最好只在应用中使用一次。制作一个小插件并将值添加到 Vue 实例,就像 Vuetify 一样。或者更简单地说,将它们提交到 vuex 并从那里读取。

【讨论】:

  • 这对我不起作用 - 我收到以下错误:10:25 error Expected to return a value in computed function vue/return-in-computed-property
  • 它必须是一个 eslint 规则。 Eslint 无法推断这里总会有返回值。埃斯林特因这些案件而臭名昭著。您可以安全地为此行/文件添加“eslint 忽略”。
  • 非常感谢您的澄清!是否还有一种方法可以将此实用程序函数导入不是用 setup() 编写的组件(使用选项)?
  • 必须在设置方法中使用。您可以创建一个新的设置方法,调用该函数并返回它。在同一个组件中同时使用composition api和options api是很正常的。
  • 你好,我正在尝试让它在我的项目中工作,但在理解如何使用这个插件时遇到了一些麻烦。我真的只是在寻找宽度,但我已经使用了您编写的全部代码。我已将代码的最高位卸载到window-width.ts 文件中,并尝试在另一个组件中访问它们。我不太了解您的 const { width, type } = useBreakpoints() 中使用的解构,我对 Vue 和使用插件还是有点陌生​​,所以也许这只是一个基本的误解,但如果您有任何想法,我将不胜感激!
【解决方案5】:

这可能真的为时已晚,但如果你不想要更简单的方法,你可以安装 npm https://www.npmjs.com/package/vue-window-sizeimport windowWidth from 'vue-window-size';

或者这个用composition 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
        }
    }

【讨论】:

  • 永远不会太晚!
【解决方案6】:

我的回答可能会迟到,但以上都没有对我有用,所以这就是我在这个主题上找到的! :)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2020-01-29
    • 2016-06-16
    • 2020-04-20
    相关资源
    最近更新 更多