目录
一、项目场景:
项目场景:当我npm run serve运行项目时正常显示,但npm run build构建项目后打开dist目录下的index.html运行时显示报错。
二、报错原因
报错原因:错误解释 "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'wrapper')" 表明在 JavaScript 代码中尝试访问一个未定义对象的 wrapper属性。
<template>
<div :ref="refName">
<div class="box">小炑吖</div>
</div>
</template>
<script>
import { ref, onMounted, getCurrentInstance } from 'vue';
export default {
name: 'FlyBox',
setup() {
const width = ref(0)
const height = ref(0)
const refName = 'wrapper'
const init = () => {
const instance = getCurrentInstance()
// 此处dom未访问到一个未定义对象的 wrapper 属性。
const dom = instance.ctx.$refs[refName]
width.value = dom.clientWidth
height.value = dom.clientHeight
}
onMounted(() => {
init()
})
return {
width, height, refName
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
position: relative;
width: 100%;
height: 100%;
.box {
width: 100px;
height: 100px;
padding: 2px;
box-sizing: border-box;
background: aqua;
}
}
</style>
三、原因分析:
错误信息 "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'wrapper')" 表明在 JavaScript 代码中尝试访问一个未定义对象的 wrapper属性。在 Vue 3 中,如果你遇到这个错误,很可能是因为你在访问响应式引用之前,该引用还没有被正确初始化或者该引用根本就不存在。
这个问题可能有几个原因:
引用未定义:
refName
变量可能包含了一个不存在的引用名,或者该引用尚未在Vue组件的模板中定义。组件未挂载:如果你正在一个Vue组件的生命周期钩子中访问
$refs
,比如在created
钩子中,此时DOM可能还没有挂载,因此$refs
对象将是空的。通常,你应该在mounted
钩子中访问$refs
,因为此时DOM已经挂载完毕。异步问题:如果你在某个异步操作(比如Promise或setTimeout)的回调中访问
$refs
,可能由于组件已经被销毁或状态已经改变,导致$refs
不再有效。为了解决这个问题,你可以尝试以下步骤:
检查对象初始化:
确保在尝试访问container
属性之前,相关的对象已经被正确初始化。如果这是一个 DOM 元素,确保在 DOM 完全加载之后访问它。如果是在 Vue 或其他框架中,确保在组件的mounted
钩子或相应的生命周期方法中进行访问。检查依赖加载:
如果container
是某个库或框架的一部分,确保这个库或框架已经被正确加载和初始化。检查是否有任何异步加载的脚本或模块,并确保它们在尝试访问container
之前已经准备就绪。检查模块导入:
如果您是从某个模块导入container
,确保导入语句是正确的,并且该模块确实导出了container
。查看文档或示例:
如果datav.umd.js
是第三方库,查看该库的文档或示例代码,看是否有关于如何正确初始化或使用该库的指导。调试:
使用console.log
语句来打印出相关对象,在访问container
之前检查它是否已定义。
例如:
if (instance.ctx.$refs && instance.ctx.$refs[refName]) {
// 安全地访问 instance.ctx.$refs[refName].wrapper
const dom = instance.ctx.$refs[refName];
} else {
// 处理$refs不存在的情况
console.error('无法找到指定的引用:', refName);
}
四、解决方案:
解析:通过打印调试发现无法找到指定的引用。可能是vue3打包后的bug,在 Vue3 实例或组件的
setup
函数中,你可以通过$refs
对象访问这些元素或组件的引用。但是,直接在setup
函数中访问$refs
是不被推荐的,因为refs
并不是响应式的,并且在setup
函数中它们可能还未被定义。
替换方案:
-
使用
ref
函数:你可以在模板中使用ref
属性,然后在setup
函数中使用ref
函数来创建一个响应式的引用。一旦模板被挂载,这个引用就会指向对应的 DOM 元素或组件实例。然而,即使这样,你也应该避免在setup
中直接操作这些引用,而是应该在响应式数据变化时通过计算属性或方法来间接更新它们。
<template>
<div ref="wrapper">
<div class="box">小炑吖</div>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
name: 'FlyBox',
setup() {
const wrapper = ref(null)
const width = ref(0)
const height = ref(0)
onMounted(() => {
if (wrapper.value) {
console.log(wrapper.value)
const dom = wrapper.value // 访问 DOM 元素
width.value = dom.clientWidth
height.value = dom.clientHeight
}
});
return {
wrapper,width,height
};
},
};
</script>
2.这样做可以解决报错信息中的 "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'wrapper')" 错误。