聊天室(IM)的时间显示方式,参照微信

3,132 阅读2分钟

先看效果再上代码。

显示今天、昨天、具体某一天时间

5分钟内输入的信息,只显示一个时间,为这5分钟内最早发言时间

正文开始

本项目使用腾讯im,用websocket也可以的。

服务器返回的数据格式如上图,其中time是本次需要用到的,单位是 秒 的时间戳

开始代码

methods: {
    insertTimeItemToCurrentMessageList(currentMessageList) {
        let originMessageList = [...currentMessageList]; // !得到的是原数据的copy
        // !由于数组的数据是从上往下返回的,但时间最靠近现在的数据在数组后面,为方便操作,先reverse数组,最后再reverse回来就好
        originMessageList.reverse(); 
        let newMessageList = []; // !待插入
        let compareTime;
        originMessageList.forEach((item, index) => {
            if (!compareTime) { //! compareTime不存在  是第一条数据
                compareTime = item.time;
            } else { // !第二条数据后
                if (Math.abs(compareTime - item.time) < 300) { // !跟compareTime相差5分钟以内
                    // !不用做
                } else {
                    newMessageList.push({
                        type: 'addTime',
                        time: originMessageList[index - 1].time // !找到上一项的时间,这个才是5分钟内最早的时间
                    });
                    compareTime = item.time;// !compareTime 重置
                }
            }
            newMessageList.push(item);
            if (index === originMessageList.length - 1) { // !如果是最后的数据
                newMessageList.push({
                    type: 'addTime',
                    time: item.time
                });
            }
        });
        newMessageList.reverse();
        return newMessageList;
    }
}

得到的新数组如上图,type为'addTime'的就可以渲染时间了

接下来就是显示今天、昨天、具体某一天时间的代码

<div class="time" v-if="message.type=== 'addTime'">
    {{ calculateTime(message.time) }}
</div>
import { getFullDate, isToday, isYesterday, getTime } from '@/utils/im/date';
methods: {
    calculateTime(time) {
        if (isToday(new Date(time * 1000))) {
            return getTime(new Date(time * 1000));
        } else if (isYesterday(time * 1000)) {
            return '昨天  ' + getTime(new Date(time * 1000));
        } else {
            return getFullDate(new Date(time * 1000)); 
        }
    }
}

getFullDate, isToday, isYesterday, getTime代码,我真是好人做到底。。。

/**
 * 返回年月日
 * @export
 * @param {Date} date
 * @param {string} [splitor='-']
 * @returns
 */
export function getDate(date, splitor = '-') {
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    const day = date.getDate();
    return `${year}${splitor}${addZeroPrefix(month)}${splitor}${addZeroPrefix(day)}`;
}

/**
 * 返回时分秒/时分
 * @export
 * @param {*} date
 * @param {boolean} [withSecond=false]
 * @returns
 */
export function getTime(date, withSecond = false) {
    const hour = date.getHours();
    const minute = date.getMinutes();
    const second = date.getSeconds();
    return withSecond ? `${addZeroPrefix(hour)}:${addZeroPrefix(minute)}:${addZeroPrefix(second)}` : `${hour}:${addZeroPrefix(minute)}`;
}

export function getFullDate(date) {
    return `${getDate(date)} ${getTime(date)}`;
}

export function isToday(date) {
    return date.toDateString() === new Date().toDateString();
}

export function isYesterday(time) { // !注意这里传入time,我懒得统一格式。。。
    const date = new Date();
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const today = `${year}/${month}/${day}`;
    const todayTime = new Date(today).getTime(); // 当天凌晨的时间
    const yesterdayTime = new Date(todayTime - 24 * 60 * 60 * 1000).getTime(); // 昨天凌晨的时间
    return time < todayTime && yesterdayTime <= time;
}

/**
 * 个位数,加0前缀
 * @param {*} number
 * @returns
 */
function addZeroPrefix(number) {
    return number < 10 ? `0${number}` : number;
}

第一次写得这么详细。。。求点赞、三连,谢谢啦,你的点点,是我后续文章的动力哈,谢谢各位。