更新记录
1.0.3(2026-10-13)
- 修复
bubbleBackground 属性不生效:此前传值会落回默认深色背景,现气泡主体与箭头统一使用自定义背景
- 修复长按弹出气泡后继续拖动手指仍会触发左滑的问题(气泡打开时拦截滑动)
- 修复气泡弹出瞬间在左上角一闪再跳位的问题:量测完成前保持隐藏
- 分割线起始位置改为随
avatarSize 动态计算,避免自定义头像尺寸后错位
平台兼容性
uni-app(5.0)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
× |
√ |
√ |
× |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
× |
√ |
√ |
√ |
√ |
√ |
√ |
其他
| 多语言 |
暗黑模式 |
宽屏模式 |
蒸汽模式 |
| × |
× |
√ |
× |
hy-message-list 仿QQ消息列表
hy-message-list 是一个 uni-app(Vue2 / Vue3) 的仿 QQ 消息列表组件,数据驱动、开箱即用:
- 传入
messages 数组即可渲染完整会话列表;
- 支持左滑露出操作栏(收藏、标记已读、删除等,数量与颜色可配);
- 支持长按弹出气泡操作菜单(可开关,自动避让屏幕边界,保证完整可见);
- 头像支持圆形 / 方形 / 圆角;标题、内容、时间齐全;支持未读数字角标与小红点两种通知形式。
同时提供 uni-app x 版本:hy-message-list-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 目录放入项目的 uni_modules 目录即可,组件已支持 easycom,无需手动 import。
基本用法
<template>
<hy-message-list :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>
export default {
data() {
return {
messages: [
{ id: 1, avatar: '/static/a.png', title: '张三', content: '晚上一起吃饭吗?', time: '12:30', badge: 3 },
{ id: 2, avatar: '/static/b.png', title: '产品群', content: '李四:需求已更新', time: '11:02', badge: 99, dot: true },
{ id: 3, avatar: '/static/c.png', title: '王五', content: '收到,谢谢!', time: '昨天', dot: true }
],
actions: [
{ text: '标为未读', background: '#f0a020' },
{ text: '置顶', background: '#3b7cff' },
{ text: '删除', background: '#f43b3b' }
],
bubbleActions: [
{ text: '复制' },
{ text: '转发' },
{ text: '撤回' }
]
}
},
methods: {
onItemClick(e) {
uni.showToast({ title: '点击:' + e.item.title, icon: 'none' })
},
onAction(e) {
uni.showToast({ title: e.action.text + ':' + e.item.title, icon: 'none' })
},
onBubbleAction(e) {
uni.showToast({ title: e.action.text + ':' + e.item.title, icon: 'none' })
}
}
}
</script>
完整可运行示例见本工程 pages/message-list/message-list.vue。
数据结构
MessageItem
| 字段 |
类型 |
说明 |
| id |
String / Number |
唯一标识,建议必填(作为列表 key) |
| 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 |
Array |
[] |
消息列表数据 |
| actions |
Array |
[] |
左滑操作项数组 |
| 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 |
Array |
[] |
气泡操作项数组 |
| 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 / iOS) |
√ |
| H5 / PC |
√ |
| 微信 / 支付宝 / 头条 / 百度 / 快手 / QQ / 飞书 / 小红书小程序 |
√ |
| 华为快应用 / 联盟快应用 |
√ |
注意事项
- 组件为数据驱动的整列列表,数据请通过
messages 传入,不要在外层再用 v-for 包裹。
actions 数量较多时建议设置 maxActions 限制显示数量;操作栏采用 flex 布局并限制在容器宽度内,不会横向溢出页面,超宽时按钮会等比压缩并对文字做省略。
- 长按气泡的位置基于
uni.createSelectorQuery 实测行位置计算,默认在消息上方弹出;上方空间不足时自动改为下方并夹紧到屏幕内,保证完整可见。
- 左滑与气泡互斥:打开其中一个会自动收起另一个;点击消息、开始滑动、点击气泡遮罩均会统一收起。
- 本组件不涉及输入框,无
input / textarea 兼容性问题。