Vue 3 无法访问Prop对象中子数组的问题排查
Vue3/InertiaJS动态下拉列表Prop数据访问问题
在Vue3/InertiaJS项目中实现动态下拉列表时,读取Laravel通过Inertia传递的Prop数据填充下拉框遇到异常,核心问题出在updateApprovers()函数:
- 通过
const area = props.areas.filter(area => area.id === parseInt(event.target.value))能筛选出目标area对象,console.log({area})可输出结果 - 但访问
area.approvers调用map时触发错误:
Uncaught TypeError: can't access property "map", area.approvers is undefined
- 尝试
area.value.approvers仍报错,Vue开发者工具显示approvers数组存在但无法访问
完整代码
<script setup> import {Head, Link, useForm} from '@inertiajs/inertia-vue3' import SelectInput from '@/Components/ping/SelectInput.vue' import {ref} from 'vue'; const props = defineProps({ areas: [ { id:1, name:"Club", approvers: [ { id:12, first_name: "Joe", last_name: "Blow" } ] }, { id:2, name:"Adult Small Bore", approvers: [ { id:34, first_name: "Sam", last_name: "Snead" } ] }, { id:3, name:"Appleseed", approvers: [ { id:56, first_name: "Johhny", last_name: "Appleseed" } ] }, { id:4, name:"Archery", approvers: [ { id:56, first_name: "Jim", last_name: "Beam" }, { id:56, first_name: "Jack", last_name: "Daniels" } ] }, { id:5, name:"Armed Women of America", approvers: [ { id: 99, first_name: "Amelia", last_name: "Earhart" } ] } ] }) const form = useForm({ date: '', hours: '', area: '', reason: '', comments: '', approver: '' }); let selectApprovers = ref([]); function updateApprovers(event) { const area = props.areas.filter(area => area.id === parseInt(event.target.value)); console.log({area}); selectApprovers.value = area.approvers.map(function (item) { return { id: item.id, name: item.first_name + ' ' + item.last_name } }); selectApprovers.value = approvers; } function store() { form.post(`/admin/work-hours`) } </script> <template> <div> <form @submit.prevent="store"> <select-input v-model="form.area" :error="form.errors.area" class="pb-8 pr-6 w-full lg:w-1/2" label="Area" @change="updateApprovers"> <option :value="null" /> <option v-for="area in props.areas" :key="area.id" :value="area.id">{{ area.name }}</option> </select-input> <select-input v-model="form.approver" :error="form.errors.approver" class="pb-8 pr-6 w-full lg:w-1/2" label="Approver"> <option :value="null" /> <option v-for="approver in selectApprovers" :key="approver.id" :value="approver.id">{{ approver.name }}</option> </select-input> </form> </div> </template>
注:<select-input>是标准<select>元素的封装组件。
问题原因及解决方法
核心问题是filter()方法返回的是数组,哪怕只匹配到一个元素,结果也是长度为1的数组,直接访问area.approvers相当于访问数组的approvers属性,自然不存在。
修改后的updateApprovers()函数
function updateApprovers(event) { const areaId = parseInt(event.target.value); // 用find获取单个匹配对象,而非filter返回的数组 const area = props.areas.find(area => area.id === areaId); if (area?.approvers) { selectApprovers.value = area.approvers.map(item => ({ id: item.id, name: `${item.first_name} ${item.last_name}` })); } else { // 无匹配区域时清空审批人列表 selectApprovers.value = []; } }
额外优化建议
- 定义Props时,推荐用类型校验替代直接写默认值,更符合Vue3规范:
const props = defineProps({ areas: { type: Array, required: true, // 可选:添加结构校验确保数据格式正确 validator: (value) => { return value.every(item => typeof item.id === 'number' && typeof item.name === 'string' && Array.isArray(item.approvers) ); } } })
- 模板中
v-for="area in props.areas"可简化为v-for="area in areas",setup中props已自动暴露。
内容的提问来源于stack exchange,提问作者wonder95
相关产品推荐
相关产品推荐

