はじめに
Vue でテーブルを作成する際、ネストされたオブジェクトの値を取得しようとして、 N/A や undefined になってしまう問題 に直面したことはありませんか?
たとえば、以下のようなデータを CommonTable.vue に渡したとします。
{
"id": 1,
"user": {
"name": "田中 太郎"
},
"homework": "数学の問題集",
"deadline": "2024-12-31",
"status": 1
}
しかし、 user.name を取得しようとしてもうまく表示されないことがあります。
実際に私も CommonTable.vue に user.name を渡した際に、 N/A になってしまう問題に直面しました。
その 原因 と 解決方法 を詳しく解説します!
N/A になる原因
Vue では、オブジェクトのプロパティを item[header.key] のように直接取得しようとすると、ネストされたキーには対応できません。
<td v-for="(header, index) in headers" :key="index">
{{ item[header.key] || 'N/A' }} <!-- ❌ user.name は取得できない -->
</td>
上記のコードでは、 header.key = 'user.name' の場合、 item['user.name'] のように処理されてしまうため、undefined となる のです。
(JavaScript では item['user'] はオブジェクトですが、 item['user.name'] というキーは存在しません)
解決策:getValue 関数を作成する
ネストされたオブジェクトの値を正しく取得するために、 getValue 関数を作成しましょう!
修正後の CommonTabel.vue
<script setup>
import { Link } from '@inertiajs/vue3';
/**
* ネストされたキーの値を取得する関数
*/
const getValue = (item, key) => {
return key.split('.').reduce((obj, k) => obj?.[k], item) || 'N/A';
};
defineProps({
headers: Array,
items: Array,
linkRoute: String
});
</script>
<template>
<table class="table-auto w-full text-left whitespace-no-wrap">
<thead>
<tr>
<th v-for="(header, index) in headers" :key="index"
class="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"
:class="header.class">
{{ header.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td v-for="(header, index) in headers" :key="index" class="border-b-2 border-gray-200 px-4 py-3">
<template v-if="header.key === 'id'">
<Link class="text-blue-400 hover:underline" :href="route(linkRoute, { id: item.id })">
{{ item.id }}
</Link>
</template>
<template v-else-if="header.key === 'status'">
<span v-if="item.status === 1" class="inline-block w-20 text-center text-green-700 bg-green-100 rounded-lg p-2">実施中</span>
<span v-if="item.status === 0" class="inline-block w-20 text-center text-red-700 bg-red-100 rounded-lg p-2">完了</span>
</template>
<template v-else>
{{ getValue(item, header.key) }}
</template>
</td>
</tr>
</tbody>
</table>
</template>
getValue 関数の仕組み
const getValue = (item, key) => {
return key.split('.').reduce((obj, k) => obj?.[k], item) || 'N/A';
};
この関数は、以下のように動作します。
key.split('.')で、user.name→['user', 'name']のように分割reduceを使ってitemをたどるobj?.[k]を使って安全に値を取得(undefinedを回避)- 値が
undefinedの場合、'N/A'を返す
つまり、以下のように動作します。
const item = {
user: { name: "田中 太郎" }
};
getValue(item, "user.name"); // "田中 太郎"
getValue(item, "user.age"); // "N/A"(存在しないキー)
getValue(item, "homework"); // "数学の問題集"
まとめ
N/A になる原因
item[header.key]ではuser.nameのようなネストされたキーを取得できない
解決策
getValue関数を作成し、key.split('.')を使ってオブジェクトをたどる
メリット
- ネストされたデータにも対応できる
undefinedエラーを防げる- 汎用的に使える(他のコンポーネントにも応用可能)
こんな時にも応用できる!
この getValue 関数は、他の Vue コンポーネントでも活用できます!
たとえば、 フォームのバリデーションエラーの表示 や ネストされたデータのフィルタリング などにも応用できます。
Vue で undefined に悩まされたら、ぜひ getValue を試してみてください!
あなたの Vue 開発をもっと快適に!
この記事が役に立ったら、ぜひシェアしてくださいね! 🚀
質問や感想があれば、コメントで教えてください! 🎉

コメント