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

  

  

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

 🔥 个人专栏 :《 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.avatarthis._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.hqwc.cn/news/598344.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux安全加固

1.登录账号加固 /etc/login.defs 创建⽤户的默认设置⽂件 grep -Ev "^#|^$" /etc/login.defs /etc/login.defs ⽂件⽤于在创建⽤户时&#xff0c;对⽤户的⼀些基本属性做默认设置&#xff0c;例如指定⽤户 UID 和 GID 的范围&#xff0c;⽤户的过期时间&#xff0…

豆瓣9.7,这部Java神作第3版重磅上市!

Java 程序员们开年就有重磅好消息&#xff0c;《Effective Java 中文版&#xff08;原书第 3 版&#xff09;》要上市啦&#xff01; 该书的第1版出版于 2001 年&#xff0c;当时就在业界流传开来&#xff0c;受到广泛赞誉。时至今日&#xff0c;已热销近20年&#xff0c;本书…

如何搭建APP分发平台分发平台搭建教程

搭建一个APP分发平台可以帮助开发者更好地分发和管理他们的应用程序。下面是一个简要的教程&#xff0c;介绍如何搭建一个APP分发平台。 1.确定需求和功能&#xff1a;首先&#xff0c;确定你的APP分发平台的需求和功能。考虑以下几个方面&#xff1a; 用户注册和登录&#xff…

【图论】有向无环图中一个节点的所有祖先 - 邻接表(DFS)

文章目录 题目&#xff1a;有向无环图中一个节点的所有祖先题目描述代码与解题思路 题目&#xff1a;有向无环图中一个节点的所有祖先 2192. 有向无环图中一个节点的所有祖先 题目描述 代码与解题思路 func getAncestors(n int, edges [][]int) [][]int {g : make([][]int, …

题目:【序列中删除指定数字】【变种水仙花数】【数组串联】【交换奇偶位】【offsetof宏的实现】

题目一:序列中删除指定数字 #include <stdio.h>int main(){int a0;int arr[50]{0};int c0;scanf("%d",&a);for(int i0;i<a;i){scanf("%d",&arr[i]);//输入a个值}scanf("%d",&c);//输入要删除的数据int i0;int j0;for(i0;i&…

【Entity Framework】EF配置文件设置详解

【Entity Framework】EF配置文件设置详解 文章目录 【Entity Framework】EF配置文件设置详解一、概述二、实体框架配置部分三、连接字符串四、EF数据库提供程序五、EF侦听器六、将数据库操作记录到文件中七、Code First默认连接工厂八、数据库初始值设定项 一、概述 EF实体框架…

力扣热题100_链表_138_随机链表的复制

文章目录 题目链接解题思路解题代码 题目链接 138. 随机链表的复制 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&a…

《追风者》中爷叔必读的三大创业金句!2024最受欢迎的创业项目,2024新兴创业项目

作为爱奇艺2024首部破万的长剧《追风者》&#xff0c;正是因为其中蕴含了无数的人生哲理&#xff0c;处世之道可以供观众细细品味。尤其是其中爷叔的创业金句&#xff0c;更是给了每个初次创业的受挫者鼓励和指引。 1、不输&#xff0c;就是赢了。不比谁赚得多&#xff0c;不比…

元宇宙虚拟空间的角色初始化(六)

前言 该文章主要讲元宇宙虚拟空间的角色初始化&#xff0c;基本核心技术点&#xff0c;不多说&#xff0c;直接引入正题。 角色初始化 在调用渲染前&#xff0c;打印一下更新的列表 console.log(this.updatables); this.render(this);; 这里看到有很多要更新的 这…

java流式计算Stream

java流式计算Stream 流(Stream)到底是什么呢? 是数据渠道&#xff0c;用于操作数据源&#xff08;集合、数组等&#xff09;所生成的元素序列。 “集合讲的是数据&#xff0c;流讲的是计算! ” 特点&#xff1a; Stream自己不会存储元素。 Stream不会改变源对象。相反&#x…

职场必修经验:一位测试大神的软件测试工作经验总结

这篇文章&#xff0c;整理下测试工作经验分享 最近&#xff0c;部门刚毕业入职的小伙伴跟大家提议&#xff0c;让大家把自己的软件测试工作经验分享一下&#xff0c;我整理了一下&#xff0c;可能不全。 测试阶段划分 1、 单个模块功能测试时间相对较长&#xff0c;但每一个…

带头双向循环链表实现

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