Vue3中如何通过传递对象Prop在子组件展示对象属性?
解决Vue3子组件中Cannot read properties of undefined (reading 'name')错误
问题场景
我们使用Vue3开发,代码如下:
父组件代码
<script setup lang="ts"> import { ref } from 'vue' import VTextFieldSmart from './VTextFieldSmart.vue' interface ShiftTemplate { name?: string } const template = ref<ShiftTemplate>({}) let dataToPass = ref<any>({}) dataToPass.value = { data: template.value, labelName: 'Name', } </script> <template> <v-text-field-smart :data="dataToPass" /> </template>
子组件(v-text-field-smart)初始代码
<template> <v-text-field v-model="params.data"> <template #label>{{ params.labelName }}<span class="text-red">*</span> </template> </v-text-field> </template> <script setup lang="ts"> import { toRef } from 'vue' const props = defineProps<{ data: any }>() const params = toRef(props, 'data') console.log('params =', params) </script>
当修改子组件模板为以下代码后,出现报错:
<template> <v-text-field v-model="params.data.name"> <template #label>{{ params.labelName }}<span class="text-red">*</span> </template> </v-text-field> </template>
报错信息:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name') at Proxy._sfc_render (VTextFieldSmart.vue:2:40)
报错原因
初始化阶段,template是空对象{},dataToPass初始也是空对象。组件渲染时,子组件的params.data可能还未被赋值,或者params.data本身没有name属性,直接访问params.data.name会因属性不存在抛出错误。
解决方法
方法1:初始化时赋予完整默认结构
在父组件中给template和dataToPass初始化完整结构,确保name属性存在:
<script setup lang="ts"> const template = ref<ShiftTemplate>({ name: '' }) let dataToPass = ref<any>({ data: { name: '' }, labelName: 'Name', }) </script>
方法2:使用可选链操作符?.
在子组件模板中通过可选链避免访问undefined属性:
<template> <v-text-field v-model="params.data?.name"> <template #label>{{ params.labelName }}<span class="text-red">*</span> </template> </v-text-field> </template>
注意:Vue3对模板中的可选链支持良好,若使用v-model配合可选链,当
params.data为undefined时,输入框不会绑定任何值,后续赋值后会自动关联。
方法3:添加条件渲染
在子组件中判断params.data存在后再渲染输入框:
<template> <v-text-field v-if="params.data" v-model="params.data.name" > <template #label>{{ params.labelName }}<span class="text-red">*</span> </template> </v-text-field> </template>
方法4:给props设置默认值
在子组件中通过defineProps设置默认值,确保data属性有基础结构:
<script setup lang="ts"> import { toRef, withDefaults } from 'vue' const props = withDefaults(defineProps<{ data?: { data: { name?: string }, labelName: string } }>(), { data: () => ({ data: { name: '' }, labelName: 'Name' }) }) const params = toRef(props, 'data') </script>
内容的提问来源于stack exchange,提问作者tesicg
相关产品推荐
相关产品推荐

