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

0sgqnhkj  于 2023-06-24  发布在  Vue.js
关注(0)|答案(2)|浏览(143)

我现在使用的获取屏幕大小的方法是:

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

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

这个问题是我的网站需要刷新才能看到我设置的只在移动的上显示的更改。
我读过关于使用window.addEventListener..能够解决这个问题,因为当屏幕调整大小时,它会不断触发一个功能。
但我正在寻找一种更直接的方法,理想情况下使用computedwatcher。我认为这不是一个好方法,使用window.innerWidth,所以任何推荐的方法都会非常感激。
先谢谢你了!

x7yiwoj4

x7yiwoj41#

这个via computed对我来说很好:How can I use window size in Vue? (How do I detect the soft keyboard?)
它总是在窗口大小改变时自动更新,而且,像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>
eit6fx6z

eit6fx6z2#

我使用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>

相关问题