Vue使用Object.keys(this.$options.components)赋值data属性报错未定义
Vue 报错
Property or method "componentNames" is not defined on the instance but referenced during render问题原因与解决方案 问题产生原因
- 核心是执行时机问题:你在
data()函数中直接访问this.$options.components时,Vue还未完成组件选项的全部初始化流程,此时this.$options.components为undefined,调用Object.keys(undefined)会直接抛出类型错误,打断data的初始化逻辑,导致componentNames没有被成功挂载到组件实例上,渲染阶段读取不到该属性就触发了报错。 - 额外隐患:即使部分场景下能读取到
this.$options.components,返回结果也会包含Vue全局注册的内置组件,不符合你只获取当前文件注册的A、B组件的预期。
解决方案
方案1:在created生命周期钩子中赋值(最便捷)
created阶段组件实例已经完成初始化,$options属性已经全部挂载完成,此时读取赋值不会报错:
<template> <v-container fluid> <v-row dense> <v-col v-for="(comp, n) in componentNames" :key="n" :cols="n === 0 ? 2 : 10" > <v-card> <component :is="comp"></component> </v-card> </v-col> </v-row> </v-container> </template> <script> import A from '../views/A.vue'; import B from '../views/B.vue'; export default { name: 'Project', data() { return { componentNames: [] // 先初始化为空数组 } }, components: { A, B }, created() { // created阶段可正常读取components选项 this.componentNames = Object.keys(this.$options.components) } }; </script>
方案2:提前定义本地组件对象(最稳妥,无冗余内容)
提前把当前文件要注册的组件存为独立对象,直接读取该对象的键值赋值,完全不用依赖this.$options,也不会混入全局注册的组件:
<template> <v-container fluid> <v-row dense> <v-col v-for="(comp, n) in componentNames" :key="n" :cols="n === 0 ? 2 : 10" > <v-card> <component :is="comp"></component> </v-card> </v-col> </v-row> </v-container> </template> <script> import A from '../views/A.vue'; import B from '../views/B.vue'; // 提前定义本地组件集合 const localComponents = { A, B } export default { name: 'Project', data() { return { // 直接读取本地集合的键,不会产生额外冗余数据 componentNames: Object.keys(localComponents) } }, components: localComponents }; </script>
内容的提问来源于stack exchange,提问作者mustafa00
相关产品推荐
相关产品推荐

