Nuxt项目中获取window innerWidth的getter无法随窗口宽度更新
问题原因
类组件中的getter确实和Vue常规写法的computed属性具备相同的响应式特性,但响应式更新的前提是getter的返回值依赖了Vue托管的响应式状态。你当前的写法直接读取原生window对象的属性,window不属于Vue的响应式数据体系,Vue无法感知到它的变化,因此该getter只会在初始化时计算一次,后续不会自动更新。
实现方案
你只需要主动监听窗口的resize事件,把窗口宽度同步到Vue的响应式状态中,再基于这个状态返回值即可:
代码示例(Vue2 类组件)
import { Vue, Component } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { // 声明响应式状态,初始化时赋值 innerWidth = process.client ? (window.innerWidth || document.documentElement.clientWidth) : false mounted() { // 绑定窗口大小变化监听 window.addEventListener('resize', this.updateInnerWidth) } beforeDestroy() { // 组件销毁时移除监听,避免内存泄漏 window.removeEventListener('resize', this.updateInnerWidth) } // 同步最新宽度到响应式状态 updateInnerWidth() { if (window.innerWidth !== undefined) { this.innerWidth = window.innerWidth } else { this.innerWidth = document.documentElement.clientWidth } } // 依赖响应式状态innerWidth,会随其变化自动更新 get viewPortWidth() { return this.innerWidth } }
优化提示
如果是Vue3环境的类组件,将生命周期钩子beforeDestroy替换为beforeUnmount即可。如果不需要宽度实时更新,可以给updateInnerWidth方法添加防抖逻辑,降低事件触发频率避免性能损耗:
// 300ms防抖示例 updateInnerWidth = this.debounce(() => { this.innerWidth = window.innerWidth || document.documentElement.clientWidth }, 300) // 简易防抖函数 debounce(func, delay) { let timer = null return function(...args) { clearTimeout(timer) timer = setTimeout(() => func.apply(this, args), delay) } }
内容的提问来源于stack exchange,提问作者Galivan
相关产品推荐
相关产品推荐

