uniapp:聊天消息列表(好友列表+私人单聊)支持App、H5、小程序

news2024/11/16 3:42:36

  

  

🎬 江城开朗的豌豆:个人主页

 🔥 个人专栏 :《 VUE 》 《 javaScript 》

 📝 个人网站 :《 江城开朗的豌豆🫛 》 

⛺️ 生活的理想,就是为了理想的生活 !

在这里插入图片描述

目录

 ⭐  文章简介(效果图展示)        

  📟 插件传送门:聊天消息列表

 📘  文章背景

  📘 平台兼容性

 📘  功能实现

废话不说直接上代码

 📟 用户列表完整代码

 📟 单人对话框 完整代码 

🔥 文章总结

📟 隐私、权限声明

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

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

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


 ⭐  文章简介(效果图展示)

      在现代社交互动中,聊天消息列表是应用程序中的关键组成部分。它不仅仅是一种通信工具,更是人们日常生活中连接感情、分享信息的重要方式之一。随着移动互联网的发展,用户在不同平台上(如App、H5、小程序等)进行聊天的需求也愈发增加。因此,设计并实现一个支持多平台、多种形式的聊天消息列表成为了开发者们的挑战之一。

        

    📟 插件传送门:聊天消息列表

 📘  文章背景

        

       最近我专注于优化我们聊天消息列表的交互体验。现在,我们的消息列表页面上有多个标签,每个标签对应着不同的聊天会话。当用户点击某个标签时,页面会流畅地滚动到相应的聊天记录位置,这样用户就可以更方便地查看他们感兴趣的对话内容。

      今天下午,我花了些时间在消息列表的交互功能上进行调整和改进。经过一番努力,我成功地实现了这一功能!在这个过程中,我逐步解决了各种技术挑战,体验着一个个问题被一一击破的成就感。这种改进用户体验的过程真是让人感到无比满足!

  📘 平台兼容性

Vue2Vue3
App快应用微信小程序支付宝小程序百度小程序字节小程序QQ小程序
HBuilderX 3.6.11 app-vue app-nvue
钉钉小程序快手小程序飞书小程序京东小程序
H5-SafariAndroid Browser微信浏览器(Android)QQ浏览器(Android)ChromeIEEdgeFirefoxPC-Safari

 📘  功能实现

废话不说直接上代码

 📟 用户列表完整代码

<template>
	<view class="page">
		<view class="list-item" v-for="(item,index) in users" :key="index" @click="connect(item)">
			<view class="avatar">
				<text class="round" v-if="item.read"></text>
				<image :src="item.avatar" mode="widthFix"></image>
			</view>
			<view class="content">
				<view class="title">
					<text class="name">{{ item.name }}</text>
					<text class="time">{{ item.time }}</text>
				</view>
				<view class="txt">{{ item.msg }}</view>
			</view>

		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				options: [{
					text: '取消',
					style: {
						backgroundColor: '#007aff'
					}
				}, {
					text: '确认',
					style: {
						backgroundColor: '#dd524d'
					}
				}],
				users: [{
						avatar: '/static/avatar/avatar1.png',
						name: '杨涛',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar2.jpg',
						name: '雨中漫步',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar3.jpeg',
						name: '糖果梦境',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar4.png',
						name: '海上日落',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar6.png',
						name: '男朋友',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar8.png',
						name: '女朋友',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar5.jpeg',
						name: '静谧之夜',
						read: 1,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar1.png',
						name: '风吹麦浪',
						read: 0,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar1.png',
						name: '路过岁月',
						read: 0,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					},
					{
						avatar: '/static/avatar/avatar1.png',
						name: '繁星点点',
						read: 0,
						time: '23:59',
						msg: '没有消息就是最好的消息'
					}
				]
			};
		},
		methods: {
			onClick(e) {
				console.log('点击了' + (e.position === 'left' ? '左侧' : '右侧') + e.content.text + '按钮')
			},
			swipeChange(e, index) {
				console.log('当前状态:' + e + ',下标:' + index)
			},
			connect(item) {
				uni.navigateTo({
					url: `/pages/message/message?name=${item.name}&avatar=${item.avatar}`
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.page {
		padding: 0 32rpx;
		color: #333;
	}

	.list-item {
		display: flex;
		padding: 30rpx 0;
		border-bottom: 1px solid #ccced3;

		.avatar {
			width: 90rpx;
			height: 90rpx;
			border-radius: 10rpx;
			margin-right: 20rpx;
			position: relative;

			.round {
				position: absolute;
				width: 14rpx;
				height: 14rpx;
				border-radius: 50%;
				background: #ef5656;
				top: -4rpx;
				right: -4rpx;
				z-index: 1;
			}

			image {
				width: 100%;
				height: 100%;
				border-radius: 10rpx;
			}
		}

		.content {
			flex: 1;

			.title {
				display: flex;
				justify-content: space-between;

				.name {
					font-weight: bold;
				}

				.time {
					color: #999;
					font-size: 24rpx;
				}
			}

			.txt {
				margin-top: 10rpx;
				overflow: hidden;
				text-overflow: ellipsis;
				display: -webkit-box;
				-webkit-line-clamp: 1;
				-webkit-box-orient: vertical;
				text-align: left;
				color: #999;
				font-size: 26rpx;
			}
		}
	}
</style>
 📟 单人对话框 完整代码

<template>
	<view class="page">
		<scroll-view class="scroll-view" scroll-y scroll-with-animation :scroll-top="top">
			<view style="padding: 30rpx 30rpx 240rpx;">
				<view class="message" :class="[item.userType]" v-for="(item,index) in list" :key="index">
					<image :src="item.avatar" v-if="item.userType === 'friend'" class="avatar" mode="widthFix"></image>
					<view class="content" v-if="item.messageType === 'image'">
						<image :src="item.content" mode="widthFix"></image>
					</view>
					<view class="content" v-else>
						{{ item.content }}
					</view>
					<image :src="item.avatar" v-if="item.userType === 'self'" class="avatar" mode="widthFix"></image>
				</view>
			</view>
		</scroll-view>
		<view class="tool">
			<input type="text" v-model="content" class="input" @confirm="send" />
			<image src="/static/photo.png" mode="widthFix" class="thumb" @click="chooseImage"></image>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				content: '',
				list: [],
				top: 0
			};
		},
		onLoad(options) {
			uni.setNavigationBarTitle({
				title: options.name
			})
			this._friendAvatar = options.avatar
			this._selfAvatar = '/static/avatar/avatar5.jpeg'
			this.list = [
				{
					content: '对方历史回复消息',
					userType: 'friend',
					avatar: this._friendAvatar
				},
				{
					content: '历史消息',
					userType: 'self',
					avatar: this._selfAvatar
				}
			]
		},
		methods: {
			send() {
				this.list.push({
					content: this.content,
					userType: 'self',
					avatar: this._selfAvatar
				})
				this.content = ''
				this.scrollToBottom()
				// 模拟对方回复
				setTimeout(()=>{
					this.list.push({
						content: '周末什么安排',
						userType: 'friend',
						avatar: this._friendAvatar
					})
					this.scrollToBottom()
				}, 1500)
			},
			chooseImage() {
				uni.chooseImage({
					// sourceType: 'album',
					success: (res) => {
						this.list.push({
							content: res.tempFilePaths[0],
							userType: 'self',
							messageType: 'image',
							avatar: this._selfAvatar
						})
						this.scrollToBottom()
						// 模拟对方回复
						setTimeout(()=>{
							this.list.push({
								content: '你好呀,朋友~',
								userType: 'friend',
								avatar: this._friendAvatar
							})
							this.scrollToBottom()
						}, 1500)
					}
				})
			},
			scrollToBottom() {
				this.top = this.list.length * 1000
			}
		}
	}
</script>

<style lang="scss" scoped>
	.scroll-view {
		/* #ifdef H5 */
		height: calc(100vh - 44px);
		/* #endif */
		/* #ifndef H5 */
		height: 100vh;
		/* #endif */
		background: #eee;
		box-sizing: border-box;
	}
	.message {
		display: flex;
		align-items: flex-start;
		margin-bottom: 30rpx;
		
		.avatar {
			width: 80rpx;
			height: 80rpx;
			border-radius: 10rpx;
			margin-right: 30rpx;
		}
		.content {
			min-height: 80rpx;
			max-width: 60vw;
			box-sizing: border-box;
			font-size: 28rpx;
			line-height: 1.3;
			padding: 20rpx;
			border-radius: 10rpx;
			background: #fff;
			image {
				width: 200rpx;
			}
		}
		&.self {
			justify-content: flex-end;
			.avatar {
				margin: 0 0 0 30rpx;
			}
			.content {
				position: relative;
				&::after {
					position: absolute;
					content: '';
					width: 0;
					height: 0;
					border: 16rpx solid transparent;
					border-left: 16rpx solid #fff;
					right: -28rpx;
					top: 24rpx;
				}
			}
		}
		&.friend {
			.content {
				position: relative;
				&::after {
					position: absolute;
					content: '';
					width: 0;
					height: 0;
					border: 16rpx solid transparent;
					border-right: 16rpx solid #fff;
					left: -28rpx;
					top: 24rpx;
				}
			}
		}
	}

	.tool {
		position: fixed;
		width: 100%;
		min-height: 120rpx;
		left: 0;
		bottom: 0;
		background: #fff;
		display: flex;
		align-items: flex-start;
		box-sizing: border-box;
		padding: 20rpx 24rpx 20rpx 40rpx;
		padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)/2) !important;
		padding-bottom: calc(20rpx + env(safe-area-inset-bottom)/2) !important;
		.input {
			background: #eee;
			border-radius: 10rpx;
			height: 70rpx;
			margin-right: 30rpx;
			flex: 1;
			padding: 0 20rpx;
			box-sizing: border-box;
			font-size: 28rpx;
		}
		.thumb {
			width: 64rpx;
		}
	}
</style>

 

🔥 文章总结

📟 隐私、权限声明

         如说明表达还不够清楚,不清楚怎么使用可导入完整示例项目运行体验和希望对大家有帮助!

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

无,开箱即用

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

插件不采集任何数据

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

没有任何广告,纯分享,方便自己,同时也方便其他能用的的前端好朋友

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

使用插件有任何问题欢迎加入QQ讨论群:

作者QQ群:906392632(未满)

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1575191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python小白入门教程:手把手教你安装最新版本Anaconda及运行第一个程序

1、Anaconda是什么&#xff1f; 其实通过百度搜索就能了解到&#xff0c;再次可以看下它自己官网的介绍&#xff1a;如下 简单的说&#xff0c;它就是一个集成的管理软件&#xff0c;管理很多工具包 2、为什么安装Anaconda&#xff1f; 简单的说&#xff0c;就是为了方便&am…

QMC5883芯片I2C驱动开发指南

这个芯片纯国产挺好用的&#xff0c;电路很好设计&#xff0c;我这垃圾焊功&#xff0c;纯手焊&#xff0c;&#xff0c;居然能用。 第一部分 硬件连接 画的很简陋&#xff0c;看看就可以了。 第二部分 软件驱动 I2C的具体时序实现需要自己搞定&#xff01;&#xff01; 2…

软件设计师30--数据库系统章节回顾

软件设计师30--数据库系统章节回顾 章节重要内容考情分析 章节重要内容 考情分析

【QT+QGIS跨平台编译】056:【pdal_json_schema+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、pdal_json_schema介绍二、pdal下载三、文件分析四、pro文件五、编译实践一、pdal_json_schema介绍 pdal_json_schema 是与 PDAL(Point Data Abstraction Library)相关的 JSON 模式文件。PDAL 是一个用于处理和分析点云数据的开源库。JSON 模式…

Win UI3开发笔记(九)关于图标Win10乱码问题

1、最开始的问题&#xff0c;winui3 gallery软件的左侧全是乱码&#xff0c;使用icon的时候&#xff0c;设置name属性出现的全是乱码&#xff0c;所以开发涉及到这部分使用Text.Glyph属性。 2、后来出现的问题&#xff0c;靠 textbox右键有各种操作&#xff0c;前面的图标乱码…

pandas(day6 图表)

一. 计算效率 1. 测量代码运行时间 %%time %%timeit 单纯计算 代码块执行的时长 %%time _sum(np.arange(6)) CPU times: total: 0 ns Wall time: 1.66 ms用于多次运行代码块并计算平均执行时间 %%timeit _sum(np.arange(6))738 ns 10.7 ns per loop (mean std. dev. of 7…

多线程4

死锁 想获取到第二把锁&#xff0c;就需要执行完第一层大括号&#xff0c;想要执行完第一层大括号&#xff0c;就要先获取到第二层的锁。 synchronized (counter2){ synchronized (counter2){} } 例子:t2先启动&#xff0c;t2进行加锁后一定成功&#xff0c;但是如果t2进行二…

Revit模型进入虚幻引擎UE5教程

一、背景 小伙伴们是否有Revit进入虚幻引擎交互的需求呢&#xff1f; 二、实现功能 1.Revit进入虚幻UE5,包含模型属性&#xff0c;材质等 2.实现BIM构件点选&#xff0c;高亮&#xff0c;属性展示 3.实现BIM模型分层显示&#xff0c;爆炸等效果 三、教程地址 教程&#x…

JavaEE——手把手教你实现简单的 servlet 项目

文章目录 一、什么是 Servlet二、创建一个简单的 Servlet 程序1. 创建项目2.引入依赖3. 创建目录4.编写代码5. 打包程序6. 部署7.验证整体过程总结 三、使用 Smart Tomcat 插件简化项目创建四、创建项目时可能遇到的几个问题。 一、什么是 Servlet Servlet 是一种实现 动态页面…

“Java泛型” 得所憩,落日美酒聊共挥

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…

2024 年广东省职业院校技能大赛(高职组)“云计算应用”赛项样题 3

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件…

【Easy云盘 | 第十三篇】分享模块(获取目录信息、获取文件信息、创建下载链接)

文章目录 4.4.7获取目录信息4.4.8获取文件信息4.4.9创建下载链接 4.4.7获取目录信息 明天做 4.4.8获取文件信息 明天做 4.4.9创建下载链接 明天做

搜索二维矩阵2 合并两个有序链表

240. 搜索二维矩阵 II - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int i matrix.size() - 1, j 0;while(i > 0 && j < matrix[0].size()){if(matrix[i][j…

第十一届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

第十一届蓝桥杯大赛软件赛省赛C/C 大学 B 组 文章目录 第十一届蓝桥杯大赛软件赛省赛C/C 大学 B 组1、字串排序2、门牌制作3、既约分数4、蛇形填数5、跑步锻炼6、七段码7、成绩统计8、回文日期9、子串分值和10、平面切分 1、字串排序 2、门牌制作 #include<iostream>#def…

HR都关心哪有好用的人才测评工具?

人才测评工具分为两种&#xff0c;一种是测评量表&#xff0c;一种是操作量表的工具&#xff0c;在线测评的方式没有普及之前&#xff0c;很多朋友都习惯把测评量表&#xff08;测评试题&#xff09;称为测评工具&#xff0c;其实我认为量表就是量表&#xff0c;而试试量表测评…

PET-SQL:基于大模型的两阶段Text2SQL方法

简介 PET-SQL出自论文《PET-SQL: A Prompt-enhanced Two-stage Text-to-SQL Framework with Cross-consistency》&#xff0c;将基于大模型的Text2SQL分为两个阶段进行&#xff0c;在第一阶段使用数据表schema信息、数据表采样数据、相似问答问答对生成初步的SQL(PreSQL)&…

linux时间同步工具chrony的配置和时间设置的相关说明

目录 目录 介绍 1.搭建ntp服务器 2.配置ntp客户端 3.其他设置 4.客户端无法进行时间同步 介绍 目前比较流行的时间同步工具有ntpd和chrony&#xff0c;ntpd采用123/UDP端口通信&#xff0c;chrony采用323/UDP端口通信。Centos7以上版本默认安装chrony服务来同步时间&#x…

Agent相关概念(更新中)

文章目录 Agent是什么Agent中要求LLM需要具备哪些能力Function Call&#xff08;工具调用&#xff09;Plan&#xff08;规划&#xff09;memory推理&#xff08;总结&#xff09;能力 Agent的实现方式PlanAndExecuteReact Agent是什么 在LLM语境下&#xff0c;Agent可以理解为…

带头双向循环链表实现

1.结构及特性 前面我们实现了无头单向非循环链表&#xff0c;它的结构是这样的&#xff1a; 在这里的head只是一个指向头结点的指针&#xff0c;而不是带头链表的头节点。 而带头双向循环链表的逻辑结构则是这样的 这就是链表的结构&#xff0c;链表的每一个节点都有两个指针…