我有一个使用Vue构建的群聊消息.js.我目前正在获取返回如下数组的消息:

"data":[
    {
        "id":1,
        "message":"<p>yo<\/p>",
        "removed":"false",
        "user":{
            "uid":2,
            "metadata":{
                "username":"Testing"
            }
        },
        "post_date":"2018-02-24 14:30"
    },
    {
        "id":2,
        "message":"<p>test<\/p>",
        "removed":"false",
        "user":{
            "uid":1,
            "metadata":{
                "username":"Admin"
            }
        },
        "post_date":"2018-02-24 22:31"
    },
    {
        "id":3,
        "message":"<p>Wassup?<\/p>",
        "removed":"false",
        "user":{
            "uid":1,
            "metadata":{
                "username":"Admin"
            }
        },
        "post_date":"2018-02-24 22:40"
    },
    {
        "id":12,
        "message":"again for testing post date",
        "removed":"false",
        "user":{
            "uid":1,
            "metadata":{
                "username":"Admin"
            }
        },
        "post_date":"2018-03-04 00:59"
    },
    {
        "id":13,
        "message":"Hello!",
        "removed":"false",
        "user":{
            "uid":2,
            "metadata":{
                "username":"Testing"
            }
        },
        "post_date":"2018-03-04 11:13"
    },
    {
        "id":13,
        "message":"<p>Hi!</p>",
        "removed":"false",
        "user":{
            "uid":2,
            "metadata":{
                "username":"Testing"
            }
        },
        "post_date":"2018-03-04 11:13"
    },
],

目前,我只是在数据中循环,并将每条消息输出到一个单独的div.我更喜欢的是,当同一个用户连续发布多条消息时,对消息进行分组.

我该怎么办?它应该是可选的服务器端(可能是可选的group参数?)还是以某种方式在客户端完成?

EDIT

这是理想的外观:

如果我按UID/用户名对它们进行分组,问题是消息需要按顺序输出.所以,如果用户1发送三条消息,然后用户2发送两条,然后用户1发送另一条消息,那么所有用户1的消息都将被分组在一起.相反,用户1的三条消息应该分组,然后是用户2,然后它应该显示用户1的最后一条消息.

推荐答案

最近我自己解决了这个问题.

在上面的示例中,用于分组消息的核心业务逻辑可以在addMessage函数的src/store.js下找到.

除非您的服务器是also,存储所有消息,并且您有一些机制来确保所有客户机之间的因果顺序,否则我建议您在每个客户机上运行逻辑.这样,您可以确保客户在任何情况下都不会看到消息跳转.在最坏的情况下,消息会显示为未分组.

当接收到新消息时,将运行用于确定这一点的算法,因此它会在每个客户机上运行,但您也可以对其进行调整,使其适用于您的用例!如下所示(我可能使用了错误的流程图元素..抱歉).

addMessage({ state }, { msg, selfHash }) {
  let addAsNewMsg = true;
  const lastMessage = state.messages.slice(-1)[0];
  if (lastMessage && lastMessage.userHash === msg.userHash) {
    // The last message was also sent by the same user
    // Check if it arrived within the grouping threshold duration (60s)
    const lastMessageTime = moment(lastMessage.time);
    const msgTime = moment(msg.time);
    const diffSeconds = msgTime.diff(lastMessageTime, "seconds");
    if (diffSeconds <= 60) {
      addAsNewMsg = false; // We're going to be appending.. so
      lastMessage.message.push(msg.message);
      // We're going to now update the timestamp and (any) other fields.
      delete msg.message; // Since, we've already added this above
      Object.assign(lastMessage, msg); // Update with any remaining properties
    }
  }
  if (addAsNewMsg) {
    state.messages.push(msg);
  }
}

Vue.js相关问答推荐

Vue路由路径匹配行为

V-img不显示文件夹中的图像

Vue 3使用计算(computed)属性对象获取图像信息,在模板中呈现值时变为NaN

Shopware 6,使用 vue-test-utils 进行Jest 测试:渲染模板上的意外行为

vue3 + pinia:如何从?store 中获取一个值

如何在 vue2.7 中删除 slot-scope

使用 Nuxt 动态获取文件夹中的图像路径

在重复表行中

JSDoc 单文件 Vue 组件

作用域slots和 IE11 的问题

为什么组件在 v-if 下没有被销毁

如何将 ASP.NET Core 2.1 与 Vue CLI 3 集成?

如何将 vue.js 与 gulp 一起使用?

ionic - `slot` 属性已被弃用 - eslint-plugin-vue

Vue devServer 代理没有帮助,我仍然收到 CORS 错误

Vuetify v-btn 路由活动类问题

Nuxt.js - API 调用的最佳场所

Vue CLI 3 sass-resources-loader - Options.loaders 未定义

使计算的 Vue 属性依赖于当前时间?

用于 nuxt.js 构建的自定义 index.html