Vue.jsプロジェクトでElement UIのel-tableを使用し、ツリー形式のテーブルデータを初期表示時に特定の階層(例:第1階層)のみ自動展開したい場合の実装方法を解説します。この方法は遅延ロード(lazy-load)非対応のケースを前提とします。
expand-row-keysプロパティを利用することで、事前に展開したい行をキー値の配列で指定できます。ただし、このキー値の型(文字列か数値か)に注意が必要です。多くの場合、型の不一致が原因で展開が効かないケースがあります。
テンプレート部分の設定
<template>
<div class="data-table-wrapper">
<el-table
:data="treeData"
row-key="nodeId"
border
:default-expand-all="false"
:expand-row-keys="preExpandedKeys"
:tree-props="{ children: 'subItems' }"
>
<el-table-column
v-for="col in columns"
:key="col.field"
:prop="col.field"
:label="col.header"
:align="col.align || 'left'"
show-overflow-tooltip
>
<template #default="{ row }">
{{ col.formatter ? col.formatter(row[col.field]) : row[col.field] }}
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button type="text" size="small" @click="handleEdit(row)">編集</el-button>
<el-button type="text" size="small" @click="handleDelete(row.nodeId, row.parentId)">削除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
スクリプト部分の実装
<script>
export default {
name: 'TreeTableView',
data() {
return {
treeData: [],
preExpandedKeys: [],
columns: [
{ field: 'name', header: '名前', align: 'left' },
{ field: 'status', header: 'ステータス', formatter: (val) => val ? '有効' : '無効' }
]
};
},
created() {
this.loadTableData();
},
methods: {
async loadTableData() {
const response = await fetchData(); // API呼び出し
this.treeData = response.data || [];
this.$nextTick(() => {
// 第1階層(親IDがnullまたは0のノード)のnodeIdを文字列型で収集
this.preExpandedKeys = this.treeData
.filter(node => node.parentId === null || node.parentId === 0)
.map(node => String(node.nodeId)); // ← ここがポイント:数値→文字列変換
});
},
handleEdit(row) {
console.log('編集:', row);
},
handleDelete(id, parentId) {
console.log('削除:', id, parentId);
}
}
};
</script>
上記のように、expand-row-keysに渡す配列の各要素を明示的にString()でラップすることで、Element UI内部での比較処理が正しく動作し、指定した階層が自動展開されます。型の不一致による不具合はコンソールエラーが出ないため、デバッグが困難なケースが多いです。必ずキーの型を確認しましょう。