更新记录

1.0.2(2026-10-13)

  • 修复长按弹出气泡后继续拖动手指仍会触发左滑的问题(气泡打开时拦截滑动)
  • 修复气泡弹出瞬间在左上角一闪再跳位的问题:量测完成前保持隐藏
  • 分割线起始位置改为随 avatarSize 动态计算,避免自定义头像尺寸后错位

平台兼容性

uni-app x(4.66)

Chrome Safari Android iOS 鸿蒙 微信小程序
√ √ √ - - -

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × √ ×

hy-message-list-x 仿QQ消息列表

hy-message-list-x 是一个 uni-app x(uvue + UTS) 的仿 QQ 消息列表组件,数据驱动、开箱即用:

  • 传入 messages 数组即可渲染完整会话列表;
  • 支持左滑露出操作栏(收藏、标记已读、删除等,数量与颜色可配);
  • 支持长按弹出气泡操作菜单(可开关,自动避让屏幕边界,保证完整可见);
  • 头像支持圆形 / 方形 / 圆角;标题、内容、时间齐全;支持未读数字角标与小红点两种通知形式。

uni-app(Vue2 / Vue3)版本请见:hy-message-list。 本组件为 uni-app x 版本,仅适用于 uni-app x 项目。

功能特性

  • 数据驱动:messages 数组 + actions / bubbleActions 操作配置,无需手写列表结构
  • 左滑操作栏
    • 支持自定义文字颜色(actionTextColor / 单项 color)与背景(actionBackground / 单项 background)
    • 支持限制操作数量(maxActions),操作栏宽度受容器约束,永不超出页面宽度
    • 支持固定按钮宽度(actionWidth)或按内容自适应;actionRadius 可设圆角
  • 长按气泡操作栏
    • 通过 enableBubble 控制开关;bubbleDuration 控制长按触发时长
    • 位置跟随长按点:气泡以手指长按的水平位置为中心弹出,超宽时自动夹紧
    • 默认在消息上方弹出,上方空间不足自动改到下方,并做水平夹紧,保证完整落在屏幕内
    • 文字颜色(bubbleTextColor / 单项 color)与背景(bubbleBackground)可自定义
    • 长按后轻微移动或抬手会自动取消,不影响正常点击与滑动
  • 标题标记:可在标题左侧显示自定义标记文字,颜色、背景、边框、圆角、字号、内外间距均可配置
  • 互斥收起:任何时刻只允许一项左滑展开;打开左滑栏会自动收起气泡,打开气泡会自动收起左滑栏
  • 统一收起:点击任意消息、开始任意滑动、点击气泡遮罩,左滑栏与气泡栏都会同时收起
  • 通知提醒:badge 数字角标(超过 badgeMax 显示 99+)与 dot 小红点,二者均可用 showBadge / showDot 全局开关
  • 头像 avatarShape 支持 circle 圆形与 square 方形(avatarRadius 控制圆角)

安装

将 hy-message-list-x 目录放入 uni-app x 项目的 uni_modules 目录即可,组件已支持 easycom,无需手动 import。

基本用法

<template>
    <hy-message-list-x :messages="messages" :actions="actions" :bubble-actions="bubbleActions" :max-actions="3"
        avatar-shape="circle" :enable-bubble="true" @item-click="onItemClick" @action="onAction"
        @bubble-action="onBubbleAction" />
</template>

<script setup lang="uts">
    type MessageItem = {
        id ?: any,
        avatar ?: string,
        title ?: string,
        content ?: string,
        time ?: string,
        badge ?: number,
        dot ?: boolean,
        tag ?: string,
        tagColor ?: string,
        tagBackground ?: string,
        tagBorderColor ?: string
    }

    type ActionItem = {
        text : string,
        color ?: string,
        background ?: string
    }

    type ClickPayload = {
        item : MessageItem,
        index : number
    }

    type ActionPayload = {
        item : MessageItem,
        index : number,
        action : ActionItem,
        actionIndex : number
    }

    const a1 : ActionItem = { text: '标为未读', background: '#f0a020' }
    const a2 : ActionItem = { text: '置顶', background: '#3b7cff' }
    const a3 : ActionItem = { text: '删除', background: '#f43b3b' }
    const actions = ref<ActionItem[]>([a1, a2, a3])

    const b1 : ActionItem = { text: '复制' }
    const b2 : ActionItem = { text: '转发' }
    const b3 : ActionItem = { text: '撤回' }
    const bubbleActions = ref<ActionItem[]>([b1, b2, b3])

    const m1 : MessageItem = { id: 1, title: '张三', content: '晚上一起吃饭吗?', time: '12:30', badge: 3 }
    const m2 : MessageItem = { id: 2, title: '产品群', content: '李四:需求已更新', time: '11:02', dot: true }
    const messages = ref<MessageItem[]>([m1, m2])

    const onItemClick = (e : ClickPayload) => {
        uni.showToast({ title: '点击:' + e.item.title!, icon: 'none' })
    }
    const onAction = (e : ActionPayload) => {
        uni.showToast({ title: e.action.text, icon: 'none' })
    }
    const onBubbleAction = (e : ActionPayload) => {
        uni.showToast({ title: e.action.text, icon: 'none' })
    }
</script>

完整可运行示例见组件目录 example/example.uvue,将其拷入 uni-app x 工程并在 pages.json 注册后即可运行。

数据结构

MessageItem

字段 类型 说明
id any 唯一标识(可选)
avatar String 头像地址;为空时显示标题首字占位
title String 标题(会话名称)
content String 内容摘要,单行省略
time String 时间文本,如 12:30、昨天
badge Number 未读数字,>0 时显示数字角标(优先级高于 dot)
dot Boolean 是否显示小红点
tag String 标题左侧标记文字;为空则不显示
tagColor String 标记文字颜色,覆盖全局
tagBackground String 标记背景颜色,覆盖全局
tagBorderColor String 标记边框颜色,覆盖全局

ActionItem

字段 类型 说明
text String 按钮文字
color String 文字颜色,覆盖全局设置
background String 背景颜色,覆盖全局设置

属性 Props

左滑操作栏

属性 类型 默认值 说明
messages MessageItem[] [] 消息列表数据
actions ActionItem[] [] 左滑操作项数组
actionTextColor String '' 操作项默认文字颜色,单项 color 优先
actionBackground String '' 操作项默认背景颜色,单项 background 优先
actionWidth Number 0 每个操作项宽度(rpx);0 表示按内容自适应
maxActions Number 0 最多显示的操作项数量;0 表示不限制
actionRadius Number 0 操作栏圆角(rpx)
swipeThreshold Number 30 触发吸附展开的水平滑动阈值(rpx)
enableSwipe Boolean true 是否开启左滑操作

长按气泡操作栏

属性 类型 默认值 说明
enableBubble Boolean true 是否开启长按气泡
bubbleActions ActionItem[] [] 气泡操作项数组
bubbleTextColor String '' 气泡文字颜色,单项 color 优先
bubbleBackground String '' 气泡背景颜色
bubbleDuration Number 500 触发长按的时长(ms)
bubbleMaxWidth Number 0 气泡最大宽度(rpx);0 表示按内容
bubbleMargin Number 16 气泡与屏幕边缘的最小间距(rpx)

外观与通知

属性 类型 默认值 说明
avatarShape String 'circle' 头像形状:circle 圆形 / square 方形
avatarRadius Number 12 方形头像圆角(rpx),circle 时忽略
avatarSize Number 96 头像尺寸(rpx)
badgeMax Number 99 数字角标最大值,超过显示 99+
showBadge Boolean true 是否显示数字角标
showDot Boolean true 是否显示小红点
showTime Boolean true 是否显示时间
titleColor String '' 标题文字颜色
contentColor String '' 内容文字颜色
timeColor String '' 时间文字颜色
divider Boolean true 是否显示分割线

标题标记(tag)

属性 类型 默认值 说明
showTag Boolean true 是否显示标题左侧标记(消息 tag 为空时不显示)
tagTextColor String '#3b7cff' 标记文字颜色,单项 tagColor 优先
tagBackground String 'rgba(59,124,255,0.12)' 标记背景颜色,单项 tagBackground 优先
tagBorderColor String 'transparent' 标记边框颜色,单项 tagBorderColor 优先
tagBorderWidth Number 0 标记边框宽度(rpx)
tagRadius Number 6 标记圆角(rpx)
tagFontSize Number 22 标记字号(rpx)
tagPaddingH Number 10 标记水平内边距(rpx)
tagPaddingV Number 2 标记垂直内边距(rpx)

事件 Events

事件名 回调参数 说明
item-click { item, index } 点击某条消息(无左滑/气泡展开时)触发
action { item, index, action, actionIndex } 点击左滑操作项时触发
bubble-action { item, index, action, actionIndex } 点击气泡操作项时触发

方法 Methods

方法名 说明
closeActions() 收起所有左滑操作栏
closeBubble() 收起长按气泡

平台支持

平台 支持情况
App(Android) √
Web(Chrome / Safari) √

注意事项

  1. 本组件为 uni-app x(uvue + UTS) 版本,只能在 uni-app x 项目中使用;uni-app(Vue2 / Vue3)请使用 hy-message-list。
  2. 组件为数据驱动的整列列表,数据请通过 messages 传入,不要在外层再用 v-for 包裹。
  3. actions 数量较多时建议设置 maxActions 限制显示数量;操作栏采用 flex 布局并限制在容器宽度内,不会横向溢出页面,超宽时按钮会等比压缩。
  4. 长按气泡的位置基于 uni.createSelectorQuery 实测行位置计算,默认在消息上方弹出;上方空间不足时自动改为下方并夹紧到屏幕内,保证完整可见。
  5. 左滑与气泡互斥:打开其中一个会自动收起另一个;点击消息、开始滑动、点击气泡遮罩均会统一收起。
  6. 本组件不涉及输入框,无 input / textarea 兼容性问题。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。