You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 = [];
    }
}

额外优化建议

  1. 定义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)
            );
        }
    }
})
  1. 模板中v-for="area in props.areas"可简化为v-for="area in areas",setup中props已自动暴露。

内容的提问来源于stack exchange,提问作者wonder95

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:40:50