Vue3 Composition API:将多维数组Props转为姓名-座位聚合列表
Vue3 Composition API 实现姓名-座位聚合展示
问题描述
使用Vue3 Composition API开发时,页面加载后获取到如下格式的Props数组:
[ {name: 'Jack', seat: '12', id: 1, ...}, {name: 'Jack', seat: '13', id: 2, ...}, {name: 'Luis', seat: '21', id: 3, ...}, {name: 'Manuel', seat: '4', id: 4, ...}, {name: 'Jack', seat: '14', id: 5, ...}, ... ]
该数组已用于渲染逐条展示的标准列表,现在需要在列表后新增表格,按姓名聚合对应座位列表(一人多座时展示多个座位),预期效果如下:
Jack: 12,13,14 Luis: 21 Manuel: 4,5,6 ....
尝试直接用模板实现时出现换行错误或跳行问题,要求不改动原Props结构(避免影响原有列表)。
解决思路与实现
1. 通过计算属性聚合数据
利用Vue的computed计算属性,基于原Props数组生成聚合后的姓名-座位数据,完全不修改原Props,不会影响原有列表的渲染。
import { computed } from 'vue'; export default { props: { items: { type: Array, required: true } }, setup(props) { // 聚合姓名对应的所有座位 const aggregatedSeats = computed(() => { const seatMap = new Map(); props.items.forEach(item => { // 若当前姓名未在Map中,初始化空数组 if (!seatMap.has(item.name)) { seatMap.set(item.name, []); } // 将座位号加入对应姓名的数组 seatMap.get(item.name).push(item.seat); }); // 转换为数组格式,方便模板遍历 return Array.from(seatMap.entries()).map(([name, seats]) => ({ name, seatsStr: seats.join(',') // 提前拼接成字符串,避免模板处理循环 })); }); return { aggregatedSeats }; } };
2. 模板渲染聚合表格
使用聚合后的数组渲染表格,结构清晰,避免直接在模板中处理循环拼接导致的格式问题:
<!-- 原有逐条展示的列表(保持不变) --> <ul class="original-list"> <li v-for="item in items" :key="item.id"> {{ item.name }} - 座位:{{ item.seat }} </li> </ul> <!-- 新增的聚合表格 --> <table class="aggregated-table"> <thead> <tr> <th>姓名</th> <th>座位列表</th> </tr> </thead> <tbody> <tr v-for="entry in aggregatedSeats" :key="entry.name"> <td>{{ entry.name }}</td> <td>{{ entry.seatsStr }}</td> </tr> </tbody> </table>
关键说明
- 计算属性
aggregatedSeats仅基于原Props生成新数据,不会修改原数组,完全兼容原有列表的逻辑; - 使用
Map进行聚合操作,时间复杂度为O(n),处理大数组时效率更高; - 提前将座位数组拼接为字符串,避免在模板中使用
v-for拼接导致的DOM渲染异常(如换行、跳行),保证格式符合预期。
内容的提问来源于stack exchange,提问作者Dierre
相关产品推荐
相关产品推荐

