Vue.js 像 CSS 媒体查询一样获取屏幕大小

问题描述 投票:0回答:3

我现在使用的获取屏幕尺寸的方法是:

export const state = () => ({
  deviceType: window.innerWidth <= 600 ? 'mobile' : 'desktop',
})

export const getters = {
  getDeviceType(state) {
    return state.deviceType
  }
}

这个问题是我的网站需要刷新才能看到更改我设置的应该只出现在移动设备上。

我读过有关使用

window.addEventListener..

 能够解决此问题的内容,因为它在屏幕调整大小时不断触发功能。

但我正在寻找一种更直接的方法,最好使用

compulatedwatcher 。我认为这不是一个好方法,使用 window.innerWidth,因此任何推荐的方法将不胜感激。

提前致谢!

vue.js vuex vue-composition-api
3个回答
5
投票
这通过计算对我来说效果很好:

如何在 Vue 中使用窗口大小? (如何检测软键盘?)

一旦窗口大小发生变化,它总是会自行更新,而且,就像在 css 中一样,会指示断点指定。

<template> <h1>{{ type + ": " + width }}</h1> </template> <script setup> import { computed, onMounted, onUnmounted, ref } from "vue" function 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' 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 } } const { width, type } = useBreakpoints() </script>
    

2
投票
我将此解决方案与 Vue 3 和 TypeScript 结合使用。它很方便、易于使用且性能非常好,因为无论有多少组件实例使用设备信息,它都只会附加一个窗口调整大小侦听器。

唯一的问题是您必须手动将 css 中的媒体中断与此处定义的中断对齐。

import { reactive } from 'vue' export enum DeviceSize { xs, s, m, l, xl } export type DeviceInfo = { windowWidth: number, size: DeviceSize, } const calcSize = (width: number): DeviceSize => { if (width < 640) return DeviceSize.xs if (width < 1024) return DeviceSize.s if (width < 1280) return DeviceSize.m if (width < 2048) return DeviceSize.l return DeviceSize.xl } const deviceInfo = reactive({ windowWidth: window.innerWidth, size: DeviceSize.xs, }) deviceInfo.size = calcSize(window.innerWidth) window.addEventListener('resize', () => { const width = window.innerWidth deviceInfo.windowWidth = width deviceInfo.size = calcSize(width) }) export const useDevice = (): DeviceInfo => { return deviceInfo } export default useDevice
要在组件中使用它:

<script setup lang="ts"> import { useDevice, DeviceSize } from './useDevice' const device = useDevice() </script> <template> <div v-if="device.size > DeviceSize.s">Some large screen content</div> </template>
    

0
投票
我结合了 bikeman868 和 Jannik Buscha 的答案:

export enum MediaQuery { xs = 420, sm = 640, md = 768, lg = 1024, xl = 1280, '2xl' = 1440, '3xl' = 1600, '4xl' = 1920 } export function useBreakpoints() { const windowWidth = ref(window.innerWidth); const onWidthChange = () => (windowWidth.value = window.innerWidth); onMounted(() => window.addEventListener('resize', onWidthChange)); onUnmounted(() => window.removeEventListener('resize', onWidthChange)); const mediaQuery = computed(() => { for (const query of Object.keys(MediaQuery)) { if (windowWidth.value < MediaQuery[query]) { return MediaQuery[query]; } } return MediaQuery.xs; }); const width = computed(() => windowWidth.value); return { width, mediaQuery }; }
并这样使用它:

const { mediaQuery } = useBreakpoints(); if (mediaQuery.value !== MediaQuery.xs) { // Do something.. }); if (mediaQuery.value < MediaQuery.lg) { // Do something.. });
    
© www.soinside.com 2019 - 2024. All rights reserved.