英文:
Unable to access sub-array in Vue 3 prop object item
问题
在一个Vue3/InertiaJS项目中,我试图实现一个简单的动态选择列表填充,但我在读取props数据以填充下拉框时遇到问题。
<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-list>
输入只是一个标准<select>
元素的包装器。
真实应用中的props是通过Laravel 通过InertiaJS传递的。我遇到问题的地方在于updateApprovers()
。这一行工作正常:
const area = props.areas.filter(area => area.id === parseInt(event.target.value));
如console.log({area})
所示。然而,它在尝试读取area.approvers
时出现错误,并出现以下错误:
Uncaught TypeError: can't access property "map", area.approvers is undefined
我尝试过使用value
selectApprovers.value = area.value.approvers.map(function (item) {
但是我得到相同的错误。通过Vue DevTools对props进行视觉检查显示,approvers
数组是存在的;我需要做什么才能访问它?
英文:
In a Vue3/InertiaJS project, I am attempting to do a simple dynamic select list population, but I'm having issues reading the props data to populate the dropdown.
<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>
where the <select-list>
input is just a wrapper around a standard <select>
element.
The props in the real app are coming from Laravel via InertiaJS. The issue I am having is in updateApprovers()
. This line works fine:
const area = props.areas.filter(area => area.id === parseInt(event.target.value));
as seen in the console.log({area})
. However, it errors out at the next line when it tries to read area.approvers
, and I get the error
Uncaught TypeError: can't access property "map", area.approvers is undefined
I've tried using value
selectApprovers.value = area.value.approvers.map(function (item) {
but I get the same error. Visual inspection of the props in Vue dev tools shows that the approvers
array is there; what do I need to change to be able to access it?
I've tried setting up an sfc playground, but for some reason it's having issues reading the v-for
loop.
答案1
得分: 1
Array.filter
总是返回另一个 数组,所以这行代码:
const area = props.areas.filter(area => area.id === parseInt(event.target.value));
导致 area
是一个对象数组。这些单独的对象可能每个都有一个内部的 approvers
数组,但 area
数组本身没有 approvers
属性,这就是为什么 area.approvers.map()
会抛出错误。
你可以使用 area[0].approvers.map()
,但我认为更合适的是首先使用 Array.find 返回第一个匹配的 对象,然后进行映射。
function updateApprovers(event) {
const area = props.value.areas.find(
area => area.id === parseInt(event.target.value)
);
selectApprovers.value = area.approvers.map(function (item) {
return {
id: item.id,
name: item.first_name + ' ' + item.last_name
};
});
}
英文:
Array.filter always returns another array, so this line:
const area = props.areas.filter(area => area.id === parseInt(event.target.value));
results in area
being an array of objects. Those individual objects may each have an inner approvers
array, but the area
array itself has no approvers
property, which is why area.approvers.map()
throws an error.
You could do area[0].approvers.map()
, but I think a more appropriate Array function to use in the first place would be Array.find to return the first matching object which you could then map.
function updateApprovers(event) {
const area = props.value.areas.find(
area => area.id === parseInt(event.target.value)
);
selectApprovers.value = area.approvers.map(function (item) {
return {
id: item.id,
name: item.first_name + ' ' + item.last_name
};
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论