Vue.js遍历哈希映射对象时,如何对比前后消息发送者设置样式?
问题描述
现有哈希映射格式的消息对象如下:
messages = { 3: { id: 3, user_id: 1, text: "My message" }, 345: { id: 345, user_id: 2, text: "Hello There!" }, ... }
在Vue模板中,希望当前后消息的发送者(user_id)不同时,为消息添加不同样式。由于这不是数组,无法直接用messages[index + 1]或messages[index - 1]获取前后消息,需要准确获取前后消息的ID。
目前可以采用将对象转为数组的方案,找到当前消息ID的索引后对比前后发送者,但觉得这种方式不够高效,且Vue的v-for已经暴露了index,想知道在不新增额外追踪ID的变量(避免增加复杂度)的前提下,是否有更优的解决方法?
解决方案
方案一:通过计算属性转为有序数组(推荐)
直接将对象转为有序数组是最直观且性能可接受的方案,所谓的“低效”在常规消息量场景下几乎可以忽略,反而逻辑清晰、易维护。
- 在Vue组件中定义计算属性,将
messages转为按消息ID排序的数组:
computed: { sortedMessages() { // 按消息id升序排列,确保消息顺序正确 return Object.values(this.messages).sort((a, b) => a.id - b.id); } }
- 在模板中遍历该数组,利用
index直接对比当前消息与前一条消息的user_id:
<template> <div v-for="(msg, index) in sortedMessages" :key="msg.id" :class="{ 'different-sender': index > 0 && msg.user_id !== sortedMessages[index - 1].user_id }" > {{ msg.text }} </div> </template> <style> .different-sender { /* 这里添加不同发送者对应的样式 */ margin-top: 12px; border-top: 1px solid #eee; } </style>
方案二:直接遍历有序ID列表
如果不想转换整个消息对象,也可以先获取有序的消息ID列表,再通过ID索引获取前后消息进行对比:
- 定义计算属性生成有序的ID数组:
computed: { messageIds() { // 将字符串ID转为数字后排序 return Object.keys(this.messages).map(Number).sort((a, b) => a - b); } }
- 在模板中遍历ID列表,结合
index获取前后ID对应的消息:
<template> <div v-for="(msgId, index) in messageIds" :key="msgId" :class="{ 'different-sender': index > 0 && messages[msgId].user_id !== messages[messageIds[index - 1]].user_id }" > {{ messages[msgId].text }} </div> </template>
这两种方案都不需要新增额外的追踪变量,完全利用Vue的v-for和计算属性实现需求,且性能表现优异。
内容的提问来源于stack exchange,提问作者Dimitrije Drakulic
相关产品推荐
相关产品推荐

