小程序版聊天室|聊天小程序|仿微信聊天界面小程序
程序员文章站
2022-07-03 17:50:45
仿微信聊天小程序weChatRoom案例,一款基于微信小程序开发的聊天室实战项目。很早之前就有开发过一个h5版聊天室,最近又在原先思路的基础上开发了个小程序版聊天室,功能效果非常接近微信聊天,实现了消息、表情发送,小程序表情解析,图片、视频上传预览,打赏、红包等微交互场景。整体界面风格及效果挺不错哒 ......
仿微信聊天小程序wechatroom案例,一款基于微信小程序开发的聊天室实战项目。很早之前就有开发过一个,最近又在原先思路的基础上开发了个小程序版聊天室,功能效果非常接近微信聊天,实现了消息、表情发送,小程序表情解析,图片、视频上传预览,打赏、红包等微交互场景。整体界面风格及效果挺不错哒。
◆ 先睹为快
◆ 项目中用到的弹窗插件,是自己开发的小程序弹窗组件wcpop:
<!-- <>引入弹窗模板.start -->
<import src="/utils/component/wcpop/tpl.wxml" />
<template is="popup" data="{{ ...__options }}" />
<!-- <>引入弹窗模板.end -->
◆ 小程序消息记录数据
module.exports = [ { id: "msg1", msgtype: 1, isme: "", avatar: "", author: "", msg: "2019年01月20日 上午11:11", imgsrc: "", videosrc: "" }, //时间提醒 { id: "msg2", msgtype: 2, isme: "", avatar: "", author: "", msg: "当前群聊人数较多,为了信息安全,请注意聊天隐私", imgsrc: "", videosrc: "" }, //公告提醒 { id: "msg3", msgtype: 1, isme: "", avatar: "", author: "", msg: "2019年01月20日 上午11:15", imgsrc: "", videosrc: "" }, //时间提醒 { id: "msg4", msgtype: 3, isme: false, avatar: "../../img/uimg/u__chat-img01.jpg", author: "马总(alibaba)", msg: "本聊天室每日10:00开22:00关期间请各位会员遵守规则禁止发言,多次警告无效踢出聊天室,永久黑名单禁止进入。", imgsrc: "", videosrc: "" }, //文字消息【别人】 { id: "msg5", msgtype: 3, isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "老板,表示下呗!", imgsrc: "", videosrc: "" }, //文字消息【自己】 { id: "msg6", msgtype: 4, isme: false, avatar: "../../img/uimg/u__chat-img02.jpg", author: "sweet甜心", msg: "", imgsrc: "http://pic.sc.chinaz.com/files/pic/pic9/201901/hpic523.jpg", videosrc: "" }, //图片消息【别人】 { id: "msg7", msgtype: 3, isme: false, avatar: "../../img/uimg/u__chat-img12.jpg", author: "flower花花", msg: "坐等群主的红包哇!:63:", imgsrc: "", videosrc: "" }, //文字消息-含表情【别人】 { id: "msg8", msgtype: 1, isme: "", avatar: "", author: "", msg: "01月20日 下午14:35", imgsrc: "", videosrc: "" }, //时间提醒 { id: "msg9", msgtype: 3, isme: false, avatar: "../../img/uimg/u__chat-img04.jpg", author: "bbk(小龙哥)", msg: "微信公开课演讲文稿,大家有时间的话可以去看看。:33::33::33:", imgsrc: "", videosrc: "" }, //文字消息-含链接【别人】 { id: "msg10", msgtype: 5, isme: false, avatar: "../../img/uimg/u__chat-img04.jpg", author: "bbk(小龙哥)", msg: "", imgsrc: "http://p3.pstatp.com/large/tos-cn-i-0004/39a6ed910d794ea8a6d85860b3464e82", videosrc: "https://v1-tt.ixigua.com/a69066ac303ccae7a155145000555100/5c4abb6b/video/m/2208ef8c54b15ae4be9babf28a888fe6d2411612e7f20000b9e74fcbf091/?rc=anf0ngx0n25tajmzzzczm0apqhrabzu1ntu8mzqzmzu2nduzndvvqggzdslazjn1kwrzcmd5a3vyz3lybhh3zjo1qc1kygdfcwowb18tlwetl3nzlw8jbym2ljyvmjytli8tmtiuni06i28jometcsm6yhzpxgjmk2beymyrxnfsoimull4%3d&vfrom=xgplayer" }, //视频消息【别人】 { id: "msg11", msgtype: 3, isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "优秀!好棒棒呀~~ 向大佬学习。:79:", imgsrc: "", videosrc: "" }, //文字消息-含表情【自己】 { id: "msg12", msgtype: 2, isme: "", avatar: "", author: "", msg: "'luci(王巧巧)' 撤回了一条消息", imgsrc: "", videosrc: "" }, //公告提醒 { id: "msg13", msgtype: 4, isme: false, avatar: "../../img/uimg/u__chat-img11.jpg", author: "luci(王巧巧)", msg: "", imgsrc: "http://y3.ifengimg.com/bbc8b9401db0d57e/2014/0721/rdn_53ccd985694da.gif", videosrc: "" }, //图片消息【别人】 { id: "msg14", msgtype: 5, isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "", imgsrc: "http://pic.rmb.bdstatic.com/mvideo/70a0790d49998653eb2deb1cadfbdf93", videosrc: "https://vd3.bdstatic.com/mda-ik6254k2dwqi75zr/mda-ik6254k2dwqi75zr.mp4" }, //视频消息【自己】 { id: "msg15", msgtype: 6, isme: false, avatar: "../../img/uimg/u__chat-img03.jpg", author: "科比", msg: "", imgsrc: "../../img/emotion/face04/0.gif", videosrc: "" }, //文字消息-含大表情【别人】 { id: "msg16", msgtype: 3, isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "哈哈哈~~~ 能不能好好聊天,太tm搞笑了,真是笑屎我了。:28:", imgsrc: "", videosrc: "" }, //文字消息-含表情【自己】 ];
◆ 聊天页面数据处理
// pages/groupchat/groupchat.js var util = require('../../utils/util.js'); import { wcpop } from '../../utils/component/wcpop/tpl.js'; const emotions = require('./emotion-mock-data.js'); const messages = require('./chat.mock-data.js'); var emojparse = require('./emojparse.js'); page({ /** * 页面的初始数据 */ data: { cursorspacing: 15, //光标与键盘的距离 toview: "scrollbottom", //定位到聊天底部 iseditorfocus: false, //编辑器获取焦点 iseditorpreview: false, //编辑器消息预览 // 消息记录 __messages: messages, // 表情集合 __emotions: emotions.list, // 预览图片地址 previewimglist: [], }, onlaunch: function(){ // ... }, onload: function () { // 初始化解析表情 emojparse.init(this, ":_/"); // 解析消息记录里面的表情符号 var _messages = this.data.__messages; for (var i = 0, len = _messages.length; i < len; i++) { // 解析含表情的消息 if (_messages[i].msgtype == 3){ // 解析消息记录表情字符串 _messages[i].msg = { emojitextarray: emojparse.transemojstr(_messages[i].msg)}; } } this.setdata({ __messages: _messages }); }, /** * 聊天页面js功能模块------------------------------------------------- */ // 滚动聊天底部 bindtomsgbottom: function (e) { var that = this; settimeout(function(){that.setdata({ toview: "scrollbottom" });}, e ? 100 : 0); }, // 点击聊天面板区域 bindtapmsgpanel: function (e) { this.setdata({ isshowchoosepanel: false }); }, // 表情/选择区切换 bindswtemotion: function (e) { var that = this; this.setdata({ isshowchoosepanel: true, isshowemotion: true, isshowchoose: false, }); // 滚动到聊天底部 this.bindtomsgbottom(); }, bindswtchoose: function (e) { var that = this; this.setdata({ isshowchoosepanel: true, isshowemotion: false, isshowchoose: true, }); // 滚动到聊天底部 this.bindtomsgbottom(); }, // 底部多表情切换 bindswtemotionbar: function(e) { var idx = e.currenttarget.dataset.index; var _lists = this.data.__emotions; for (var i = 0, len = _lists.length; i < len; i++){ _lists[i].selected = false; } _lists[idx].selected = true; this.setdata({ __emotions: _lists }); }, // 点击大图 bindgifimagetap: function (e) { wx.showloading({title: '发送中...',}); var that = this; var _messages = this.data.__messages; var _len = _messages.length; var gifpath = e.currenttarget.dataset.path; // 消息队列 var _data = { id: `msg${++_len}`, msgtype: 6, //大表情 isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "", imgsrc: gifpath, videosrc: "" }; _messages = _messages.concat(_data); this.setdata({ __messages: _messages }); settimeout(function () { wx.hideloading(); }, 100); // 滚动到聊天底部 this.bindtomsgbottom(true); }, // 选择图片 bindchooseimage: function (e) { var that = this; var _messages = this.data.__messages; var _len = _messages.length; // 消息队列 var _data = { id: `msg${++_len}`, msgtype: 4, //发送图片 isme: true, avatar: "../../img/uimg/u__chat-img14.jpg", author: "nice奈斯", msg: "", imgsrc: "", videosrc: "" }; wx.chooseimage({ count: 1, success: function(res) { // console.log(res); // console.log(res.tempfilepaths); _data.imgsrc = res.tempfilepaths.tostring(); //把单张数组格式图片转换为字符串格式 _messages = _messages.concat(_data); that.setdata({ __messages: _messages }); // 滚动到聊天底部 that.bindtomsgbottom(true); }, }) }, // 预览图片 bindpreviewimage: function (e) { // 遍历所有当前聊天记录图片 var _src = e.currenttarget.dataset.src; var _messages = this.data.__messages; var _imglist = this.data.previewimglist; for (var i = 0, len = _messages.length; i < len; i++) { if (_messages[i].imgsrc != "" && _messages[i].msgtype == 4) { if (_imglist.indexof(_messages[i].imgsrc) == -1) { _imglist.push(_messages[i].imgsrc); } } } // preview images wx.previewimage({ current: _src, urls: _imglist, }) }, // 预览视频 bindpreviewvideo: function (e) { var _id = e.currenttarget.dataset.id; this.playcontext = wx.createvideocontext("video_" + _id, this); this.playcontext.play(); this.playcontext.requestfullscreen({ direction: 0 }); }, // 全屏事件 bindfullscreenchange: function (e) { var _id = e.currenttarget.dataset.id; this.fullchangecontext = wx.createvideocontext("video_" + _id, this); if (e.detail.fullscreen == false){ this.fullchangecontext.pause(); this.fullchangecontext.exitfullscreen(); } }, // 视频播放结束 bindendedvideo: function (e) { var _id = e.currenttarget.dataset.id; this.stopcontext = wx.createvideocontext("video_" + _id, this); this.stopcontext.stop(); this.stopcontext.exitfullscreen(); }, // 打赏 binddashang: function (e) { var dsidx = wcpop({ skin: 'android', content: ['wc__tmpl_dashang'], xclose: true, shadeclose: false, style: 'background: #f3f3f3;', }); }, // 发送红包 bindhongbao: function (e) { var hbidx = wcpop({ skin: 'android', content: ['wc__tmpl_hongbao'], xclose: true, shadeclose: false, style: 'background: #f3f3f3;', }); }, })