You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VueJS中实现响应window.innerWidth的计算属性

解决Vue计算属性不响应窗口resize的问题

嘿,这个问题我之前做移动端适配时也踩过坑!核心原因很简单:Vue的计算属性只会自动追踪Vue实例内的响应式依赖变化,而window.innerWidth是浏览器原生属性,不属于Vue的响应式系统,所以第一次计算后,就算窗口大小改变,计算属性也不会重新执行。

下面给你两种可行的解决方案,根据你的Vue版本选择即可:

方案一:Vue 2/3 选项式API写法

我们需要把窗口宽度转换成Vue能追踪的响应式变量,再让计算属性依赖它:

export default {
  data() {
    return {
      // 初始化时获取当前窗口宽度,这是响应式变量
      windowWidth: window.innerWidth
    }
  },
  computed: {
    isMobile() {
      // 现在依赖响应式的windowWidth,变化时会自动重新计算
      return this.windowWidth <= 768
    }
  },
  mounted() {
    // 定义防抖函数,避免resize事件频繁触发(可选但推荐)
    let debounceTimer
    const debouncedUpdateWidth = () => {
      clearTimeout(debounceTimer)
      debounceTimer = setTimeout(() => {
        this.windowWidth = window.innerWidth
      }, 100)
    }

    // 添加窗口resize监听
    window.addEventListener('resize', debouncedUpdateWidth)
    // 把监听函数存到实例上,方便销毁时移除
    this.resizeHandler = debouncedUpdateWidth
  },
  beforeUnmount() {
    // 组件销毁时移除监听,防止内存泄漏
    window.removeEventListener('resize', this.resizeHandler)
  }
}

方案二:Vue 3 组合式API写法

如果用的是Vue 3的<script setup>,写法会更简洁:

import { ref, computed, onMounted, onBeforeUnmount } from 'vue'

// 响应式变量存储窗口宽度
const windowWidth = ref(window.innerWidth)
// 计算属性依赖响应式变量
const isMobile = computed(() => windowWidth.value <= 768)

// 防抖函数优化性能
let debounceTimer
const updateWindowWidth = () => {
  clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    windowWidth.value = window.innerWidth
  }, 100)
}

onMounted(() => {
  // 挂载后添加监听
  window.addEventListener('resize', updateWindowWidth)
})

onBeforeUnmount(() => {
  // 销毁前移除监听
  window.removeEventListener('resize', updateWindowWidth)
})

关键细节说明:

  • 防抖函数:resize事件在窗口拖动时会每秒触发几十次,加防抖可以减少不必要的更新,提升页面性能,你可以根据需求调整防抖时间(比如100ms)。
  • 移除监听:一定要在组件销毁时移除resize事件监听,否则组件销毁后监听还存在,会造成内存泄漏。

内容的提问来源于stack exchange,提问作者Carlos Pisarello

火山引擎 最新活动