微信小程序| 用小程序复刻微信Wechat

news2025/8/12 8:27:55

📌个人主页:个人主页
​🧀 推荐专栏:小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏!从个人到商业的全套开发教程,实打实的干货分享,确定不来看看? 😻😻】
📝作者简介从web开发,再到大数据算法,踩过了无数的坑,用心总结经验教训,助你在技术生涯一臂之力!若想获取更多精彩内容,敬请订阅专栏或者关注😁😂🤣😃😆😉😊😋😍😘🥰
⭐️您的小小关注是我持续输出的动力!⭐️


干货内容推荐

🥇入门和进阶小程序开发,不可错误的精彩内容🥇 :

  • 《小程序开发必备功能的吐血整理【个人中心界面样式大全】》
  • 《微信小程序 | 动手实现双十一红包雨》
  • 《微信小程序 | 人脸识别的最终解决方案》
  • 《来接私活吧?小程序接私活必备功能-婚恋交友【附完整代码】》
  • 《吐血整理的几十款小程序登陆界面【附完整代码】》

文章目录

  • 干货内容推荐
    • 效果预览
    • 一、需求背景
    • 二、功能剖析
      • 2.1 聊天列表
        • 2.1.1 效果展示
        • 2.1.2 源码解析
      • 2.2 聊天列表
        • 2.2.1 效果展示
        • 2.2.2 源码解析
      • 2.3 朋友圈界面
        • 2.3.1 效果展示
        • 2.3.2 源码解析
    • 三、完整源码


效果预览

在这里插入图片描述


一、需求背景

微信作为熟人社交领域类的顶流。其中有非常多的功能值得借鉴和推敲。其中的用户聊天界面联系人界面特别是朋友圈界面妥妥是进行社交类应用开发的参考和借鉴的典范!

特此,本文整理了基于vue 2.0语法,结合uniapp框架,从而实现了可覆盖到移动全端的功能。同时使用了小程序端优秀的UI组件库uVIew进行构建,使得开发的成本更低,效果更好。


二、功能剖析

2.1 聊天列表

2.1.1 效果展示

在这里插入图片描述

2.1.2 源码解析

  • 在联系人聊天记录条中,使用了uView中的u-swipe-action组件,使得消息具备了滑动展示菜单操作的功能。
<u-swipe-action :show="item.show" :index="index" v-for="(item, index) in list" btn-width="160" :key="item.id" @click="click" @open="open" :options="options">
			<view class="item" :class="item.isTop ? 'bg_view' : ''" hover-class="message-hover-class" @tap="linkTo(item)">
				<image mode="aspectFill" :src="item.images" />
				
				<view class="right u-border-bottom title-wrap">
					<view class="right_top">
						<view class="right_top_name u-line-1">{{ item.name }}</view>
						<view class="right_top_time ">{{ item.updateTime }}</view>
					</view>
					<view class="right_btm ">
						<view class="u-line-1">-</view>
						<view class=""></view>
					</view>
				</view>
			</view>
		</u-swipe-action>

2.2 聊天列表

2.2.1 效果展示

在这里插入图片描述

2.2.2 源码解析

  • 在该聊天界面中,集成进了语音聊天功能,其中通过监听录音设备和用户点击录音按钮的时间长短来动态生成录音内容的大小,并将其转为mp3文件数据进行传输。
//处理录音文件
		handleRecorder({ tempFilePath,duration }) {
			let contentDuration;
			// #ifdef MP-WEIXIN
			this.voiceTime = 0;
			if (duration < 600) {
				this.voiceIconText="说话时间过短";
				setTimeout(()=>{
					this.recording = false;
				},200)
				return;
			} 
			contentDuration = duration/1000;
			// #endif
			
			// #ifdef APP-PLUS
			contentDuration = this.voiceTime +1;
			this.voiceTime = 0;
			if(contentDuration <= 0) {
				this.voiceIconText="说话时间过短";
				setTimeout(()=>{
					this.recording = false;
				},200)
				return;
			};
			// #endif
			
			this.recording = false;
			const params = {
				contentType: 2,
				content: tempFilePath,
				contentDuration: Math.ceil(contentDuration)
			};
			this.canSend && this.sendMsg(params);
		},

2.3 朋友圈界面

2.3.1 效果展示

在这里插入图片描述

2.3.2 源码解析

  • 针对用户所发的朋友圈信息,根据信息的类型:图片或者文字信息,需要根据类型进行不同的排版。针对点赞的列表需要根据用户的点赞时间进行按需排列。
<template>
	<view class="content" id="content">
		<!-- #ifdef MP-WEIXIN -->
		<u-navbar title=" " :background="{ background: '#f8f8f8' }" :border-bottom="false">
			<view class="slot-wrap" slot="right"><u-icon name="camera-fill" size="36" @click="linkToRelease"></u-icon></view>
		</u-navbar>
		<!-- #endif -->
		<view class="content-imgbox">
			<image class="bgimg" :src="_user_info.pictureBanner" mode="scaleToFill" @tap="showSheet"></image>
			<image class="headimg" :src="_user_info.headImg" @tap="linkToBusinessCard(_user_info.id)"></image>
			<text class="nickname">{{ _user_info.userName }}</text>
		</view>
		<view class="signature">
			<view class="">{{ _user_info.signature }}</view>
		</view>

		<!-- 朋友圈列表 -->
		<view class="content-circle">
			<view class="content-circle-box" v-for="(item, index) in circleData" :key="item.circleMegId">
				<view class="headimg"><image class="img" :src="item.userHeadImg" @tap="linkToBusinessCard(item.userId)"></image></view>
				<view class="content">
					<view class="content-name" @tap="linkToBusinessCard(item.userId)">{{ item.userName }}</view>
					<view class="content-desc">{{ item.content }}</view>
					<view class="content-img" v-if="item.imageList.length">
						<!-- //只有一张图时候 -->
						<view v-if="item.imageList.length == 1"><image class="img-1" :src="item.imageList[0]" mode="widthFix" @tap="previewImg(0, item.imageList)"></image></view>
						<!-- 有多张图的时候 -->
						<view v-else-if="item.imageList.length > 1">
							<view class="content-img-more">
								<image
									class="img-more"
									v-for="(src, index) in item.imageList"
									:key="index"
									:class="index % 3 == 0 && 'img-3'"
									:src="src"
									mode="aspectFill"
									@tap="previewImg(index, item.imageList)"
								></image>
							</view>
						</view>
					</view>
					<!-- 相对时间 点赞按钮等 -->
					<view class="relavivetime" :id="`comment-${'null'}-${index}`">
						<view class="time">{{ item.createTime }}</view>
						<view class="icon-box">
							<view @tap="clickThumb(item)">
								<image class="img icon-box-item thumb" :src="item.isPraise ? require('@/static/like-fill.png') : require('@/static/like.png')" mode=""></image>
							</view>
							<view @tap="handleComment(item.circleMegId, null, index)">
								<image class="img icon-box-item" :src="require('@/static/comment.png')" mode=""></image>
							</view>
						</view>
					</view>
					<!-- 点赞人 评论 -->
					<view class="msg-box">
						<view class="thumbinfo" v-if="item.praise.length">
							<image class="thumbinfo-icon" :src="require('@/static/like.png')"></image>
							<text class="thumbinfo-name" v-for="(userInfo, index) in item.praise" :key="userInfo.id" @tap="linkToBusinessCard(userInfo.id)">
								{{ userInfo.userName }}{{ index != item.praise.length - 1 ? ',' : '' }}
							</text>
						</view>
						<view class="comment" v-if="item.comment.length">
							<view
								class="comment-box"
								v-for="(comment, index) in item.comment"
								:key="index"
								hover-class="comment-hover-class"
								:id="`comment-${item.circleMegId}-${index}`"
								@tap="handleComment(item.circleMegId, comment, index)"
							>
								<text class="comment-box-name" v-if="!comment.replyUserId" @tap.stop="linkToBusinessCard(comment.userId)">{{ comment.userName }}:</text>
								<text class="comment-box-name" v-if="comment.replyUserId" @tap.stop="linkToBusinessCard(comment.userId)">
									{{ comment.userName }}
									<text class="callback">回复</text>
								</text>
								<text v-if="comment.replyUserId" class="comment-box-name" @tap.stop="linkToBusinessCard(comment.replyUserId)">{{ comment.replyUserName }}:</text>
								<text class="comment-box-content">{{ comment.content }}</text>
							</view>
						</view>
					</view>
				</view>
			</view>
			<!-- #ifdef H5 -->
			<view :style="{ height: showInput ? '100rpx' : 0 }"></view>
			<!-- #endif -->
			<!-- #ifdef APP-PLUS -->
			<view v-show="showInput" :style="{ height: viewOffsetBottom + 'px' }"></view>
			<!-- #endif -->
		</view>

		<!-- 底部聊天输入框 其实可以封装成组件的...-->
		<!-- #ifdef MP-WEIXIN -->
		<view class="input-box" v-if="showInput" id="input-box" :style="{ bottom: inputOffsetBottom > 0 ? inputOffsetBottom + 'px' : '0' }">
		<!-- #endif -->
		<!-- #ifndef MP-WEIXIN -->
		<view class="input-box" v-show="showInput" id="input-box" :style="{ bottom: inputOffsetBottom > 0 ? inputOffsetBottom + 'px' : '0' }">
		<!-- #endif -->
			<view class="input-box-flex">
				<view class="input-box-flex-grow">
					<input
						type="text"
						class="content"
						id="input"
						v-model="content"
						:adjust-position="false"
						:confirm-type="'send'"
						:confirm-hold="true"
						placeholder-style="color:#DDD;"
						:cursor-spacing="6"
						:placeholder="placeholder"
						:focus="showInput"
						@blur="blurInput"
						@confirm="sendMsg"
					/>
				</view>
				<button class="btn" type="primary" size="mini" @touchend.prevent="sendMsg">发送</button>
			</view>
		</view>

		<u-action-sheet :list="list" v-model="show" border-radius="25" safe-area-inset-bottom @click="clickAction"></u-action-sheet>
	</view>
</template>

三、完整源码

在这里插入图片描述

完整源码下载地址

觉得好用的话就给个好评吧😁🤩🥰😘😄😗😛

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

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

相关文章

新的趋势:From Big to Small and Wide data

新的趋势&#xff1a;From Big to Small and Wide data 所以&#xff0c;在这个时候&#xff0c;作为率先提出要做 MySQL 开源 HTAP 数据库的 StoneDB&#xff0c;想要稍微冷静一下。 不是说我们不做 HTAP 了&#xff0c;而是有了一个新的思路。这个思路&#xff0c;也同样来…

【模型训练】YOLOv7车辆三类别检测

YOLOv7车辆三类别检测 1、车辆三类别检测模型训练2、模型评估3、模型和数据集下载网盘链接1、本项目采用YOLOv7算法实现对车辆三类别检测,在几千多张车辆三类别数据集中训练得到,我们训练了YOLOv7、,所有指标都是在同一个验证集上得到; 2、目标类别数:3;类别名:car、bus…

【蓝桥杯选拔赛真题29】python堆砖块 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python堆砖块 一、题目要求 1、提示信息 1、编程实现 2、输入输出

WindowsServer域控的安装与卸载

搭建域服务器 1.安装域控 打开服务器管理器, 点击右上角的管理, 选择添加角色和功能 一直点击下一步,直到选择服务器角色处, 勾选Active Directory域服务器 一直下一步&#xff0c;然后点击安装 安装完毕后将此服务器提升为域控制器 自行设置DSRM的密码, 后面一直点击下一步直…

【优化调度】遗传算法求解公交车调度排班优化问题【含Matlab源码 2212期】

⛄ 一、 遗传算法简介 1 引言 公交排班问题是城市公交调度的核心内容,是公交调度人员、司乘人员进行工作以及公交车辆正常运行的基本依据。行车时刻表是按照线路的当前客流量情况,确定发车频率,提供线路车辆的首、末车时间。它是公交企业对社会的承诺,决定着为乘客服务的水平,…

2023-2028年中国花炮行业市场供需与投资预测分析报告

本报告由锐观咨询重磅推出&#xff0c;对中国花炮行业的发展现状、竞争格局及市场供需形势进行了具体分析&#xff0c;并从行业的政策环境、经济环境、社会环境及技术环境等方面分析行业面临的机遇及挑战。还重点分析了重点企业的经营现状及发展格局&#xff0c;并对未来几年行…

【Java 设计模式】简单工厂模式 静态工厂模式

简单工厂模式 & 静态工厂模式1 简单工厂模式1.1 角色1.2 点咖啡案例1.2.1 类图1.2.2 实现1.3 优点1.4 缺点2 静态工厂模式2.1 代码变动2.2 优点1 简单工厂模式 简单工厂模式并不属于 23 种设计模式。 1.1 角色 抽象产品&#xff1a;定义产品的规范&#xff0c;描述产品的…

相控阵天线(七):常规平面阵列分布(矩形阵列、三角栅格、六边形阵列和圆形阵列)

目录简介矩形栅格平面阵列三角栅格平面阵列六边形阵列圆形平面阵列空心平面阵列简介 常见的平面阵有一些基本类型&#xff0c;按照栅格形式可以进行以下划分&#xff1a;矩形栅格、三角形栅格、同心圆环和椭圆环栅格等&#xff1b;按照边界形式可以进行以下划分&#xff1a;矩…

React Native Webview 中input type=file accept=“image/*“ 无法调起相机问题排查及解决

最近在写一个react native 项目&#xff0c;其中react-native-webview库一些使用着实遇到了不少问题&#xff0c;耗时比较长&#xff0c;现在和大家分享一下。 图片上传时选择拍照是很常见的功能&#xff0c;写的h5项目一直调用正常。使用方式大概如下&#xff1a; <input…

【数据结构】—— 双链表的增删改查

❤️一名热爱Java的大一学生&#xff0c;希望与各位大佬共同学习进步❤️ &#x1f9d1;个人主页&#xff1a;周小末天天开心 各位大佬的点赞&#x1f44d; 收藏⭐ 关注✅&#xff0c;是本人学习的最大动力 感谢&#xff01; &#x1f4d5;该篇文章收录专栏—数据结构 目录 双…

艾美捷小鼠肿瘤坏死因子α-ELISpot试剂盒使用指南

ELISpot Plus for enumeration of cells secreting TNF-α This kit is ideal for users who want a convenient and sensitive assay. The assay is designed for the enumeration of cells secreting mouse TNF-α. The kit includes ELISpot plates pre-coated with monocl…

[附源码]计算机毕业设计JAVA面试刷题系统

[附源码]计算机毕业设计JAVA面试刷题系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis M…

【C++】--模拟实现vector

文章目录Constructors(构造函数)myvector()myvector(int n, const T& val T())myvector(InputIterator first, InputIterator last)拷贝构造交换函数myvector< T >& operator(myvector< T > v)迭代器扩容reserveresize插入和删除push_backpop_backinserte…

CDH启用kerberos 高可用运维实战

一、背景说明 在前的文章中介绍过《CDH集成的kerberos迁移实战》,由此也考虑到kerberos单节点可能引发的线上事故&#xff0c;所有考虑到把线上kerberos服务启用高可用。 二、环境介绍 系统版本 CentOS Linux release 7.6.1810 (Core) CM版本 Kerberos版本 三、实操…

桌面应用开发有哪些主流框架?

受益于开源技术的发展&#xff0c;以及响应快速开发的实际业务需求&#xff0c;跨平台开发不仅限于移动端跨平台&#xff0c;桌面端虽然在市场应用方面场景不像移动端那么丰富&#xff0c;但也有市场的需求。 相对于个人开发者而言&#xff0c;跨平台框架的使用&#xff0c;主要…

零基础学习下载FL Studio2023水果编曲软件

FL Studio工具常称水果编曲软件&#xff0c;是一款功能强大的编曲软件&#xff0c;集编曲&#xff0c;录音&#xff0c;剪辑&#xff0c;混音于一身&#xff0c;简单易上手&#xff0c;灵活性高&#xff0c;强大到突破想象。FL Studio&#xff0c;当前版本 FL Studio21&#xf…

Transductive Learning 和 Inductive Learning

简介 在 kipf-GCN 和 GraphSage 中&#xff0c;对 Transductive Learning 和 Inductive Learning 有了比较深刻的认识。 kipf-GCN 在其论文中提到算法属于 transductive node classification&#xff0c;也就是在训练节点embedding的时候要看到全图的节点&#xff0c;这是因为…

Linux——进程间通信(共享内存)

一、共享内存 1、定义 共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间&#xff0c;多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址&#xff0c;就好像它们是由malloc分配的一样。如果某…

47 - 父子间的冲突

---- 整理自狄泰软件唐佐林老师课程 1. 思考 子类中是否可以定义父类中的同名成员&#xff1f; 如果可以&#xff0c;如何区分&#xff1f;如果不可以&#xff0c;why&#xff1f; 1.1 编程实验&#xff1a;同名成员变量 #include <iostream> #include <string>…

操作系统导论--受限制的直接执行

受限直接执行 为了使程序尽可能快地运行&#xff0c;操作系统开发人员想出了一种技术——我们称之为受限的直接执行。 这个概念的“直接执行”部分很简单&#xff1a;只需直接在CPU上运行程序即可。因此&#xff0c;当OS希望启动程序运行时&#xff0c;它会在进程列表中为其创…