Vue中检测元素offsetHeight的计算属性未自动更新问题
问题原因
- Vue的计算属性仅会在其依赖的响应式数据发生变更时重新计算,本次场景中不存在能触发重新计算的依赖变更:
$refs本身不属于Vue的响应式数据,它是渲染完成后挂载的普通DOM引用集合,其变更不会被Vue的响应式系统追踪- DOM元素的
offsetHeight是浏览器原生DOM属性,不属于Vue响应式数据范畴,值发生变化时Vue无法感知 - 窗口 resize 事件不属于Vue默认监听的响应式变更触发源,没有触发计算属性重新执行的入口
正确实现方案
- 放弃使用计算属性实现该筛选逻辑,改用响应式data属性存储筛选结果
- 监听窗口resize事件,在事件回调中执行筛选逻辑更新响应式数据,可添加防抖优化性能
- 组件卸载时移除resize事件监听,避免内存泄漏
示例代码:
export default { props: { items: { type: Array, required: true, }, }, data() { return { filteredItems: [] } }, mounted() { // 初始化执行一次 this.updateFilteredItems() // 绑定resize监听,加100ms防抖,如无全局lodash可自行实现防抖逻辑 this.debouncedUpdate = _.debounce(this.updateFilteredItems, 100) window.addEventListener('resize', this.debouncedUpdate) }, beforeDestroy() { // 组件卸载前移除监听 window.removeEventListener('resize', this.debouncedUpdate) }, methods: { updateFilteredItems() { const all = this.$refs.items if (!Array.isArray(all)) return this.filteredItems = all.filter(x => x.offsetHeight > 300) } } }
注意:如果使用Vue3,v-for的ref默认不会自动生成数组,需要通过函数式ref手动收集DOM元素。
内容的提问来源于stack exchange,提问作者user15909643
相关产品推荐
相关产品推荐

