Uncaught TypeError: Cannot set properties of undefined (setting ‘tableHight‘) 问题
1. this 上下文丢失
原始代码中使用了普通函数作为 window.onresize 的回调
// 原始有问题的代码
mounted() {
window.onresize = function() {
this.tableHight = document.body.clientHeight - 200 + "px";
// 这里的 this 指向 window,而不是 Vue 组件实例
}
}
在 JavaScript 中,普通函数的 this 指向取决于调用方式。当 window.onresize 被触发时, this 指向的是 window 对象,而不是 Vue 组件实例。因此 this.tableHight 实际上是在尝试设置 window.tableHight 。
2. 组件销毁后的内存泄漏
更严重的问题是,当用户离开页面或组件被销毁后, window.onresize 回调仍然存在,并且可能尝试访问已经被销毁的组件实例,导致 undefined 错误。
## 解决方案
1. 使用箭头函数保持 this 上下文
mounted() {
// 使用箭头函数,this 指向组件实例
const updateHeight = () => {
this.tableHight = document.body.clientHeight - 200 + "px";
};
// 立即调用一次设置初始高度
updateHeight();
// 添加事件监听器
window.addEventListener("resize", updateHeight);
// 保存引用以便后续清理
this._updateHeightHandler = updateHeight;
}
箭头函数会"捕获"定义时的 this 值,确保在回调中 this 始终指向 Vue 组件实例。
2. 添加生命周期清理
beforeDestroy() {
// 组件销毁前移除事件监听器
if (this._updateHeightHandler) {
window.removeEventListener("resize", this._updateHeightHandler);
this._updateHeightHandler = null;
}
}
3. 使用 addEventListener 而不是直接赋值
// 不好的做法
window.onresize = function() { ... }
// 更好的做法
window.addEventListener("resize", handler);
addEventListener 的优势:
- 可以添加多个监听器而不会相互覆盖
- 更容易管理和移除
- 箭头函数确保 this 绑定 :组件实例的 tableHight 属性能被正确访问和设置
- 事件监听器管理 :使用 addEventListener/removeEventListener 提供更好的控制
- 生命周期清理 : beforeDestroy 确保组件销毁时清理资源,避免内存泄漏
- 初始化调用 : updateHeight() 立即执行确保页面加载时就有正确的高度
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)