专栏首页h5小程序聊天室|聊天对话小程序|仿微信界面
原创

小程序聊天室|聊天对话小程序|仿微信界面

微信小程序开发的仿微信聊天室weChatRoom项目|聊天小程序demo实例

基于微信小程序开发的聊天室实战案例。很早之前就有开发过一个h5版聊天室,最近又开发了个小程序版聊天室,功能效果非常接近微信聊天,实现了消息、表情发送,小程序表情解析,图片、视频上传预览,打赏、红包等功能。

// 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;',
    });
  },


})
<!-- 表情区域 -->
<view class="wrap-emotion" style="display:{{isShowEmotion ? 'block' : 'none'}};">
  <view class="emotion__cells flexbox flex__direction-column">
	<!-- //表情swiper -->
	<block wx:for="{{__emotions}}" wx:key="index" wx:for-item="item">
	<view class="emotion__cells-swiper flex1 {{item.selected ? 'cur' : ''}}">
	  <swiper indicator-dots="true" duration="200">
		<block wx:for="{{item.lists}}" wx:key="*item" wx:for-item="item2">
		  <swiper-item class="{{item.type}}">
			<view class="item">
			  <block wx:for="{{item2.nodes}}" wx:key="*item2" wx:for-item="item3">
				<label wx:if="{{item.type == 'face__sm-list'}}" bindtap="bindEmotionTap" data-emot=":{{item3}}:">
				  <image wx:if="{{item3 == 'del'}}" src="../../img/wchat/icon__emotion-del.png"></image>
				  <image wx:else src="{{item.path}}/{{item3}}.gif"></image>
				</label>
				<!-- 大表情 -->
				<label wx:if="{{item.type == 'face__lg-list'}}" bindtap="bindGifImageTap" data-path="{{item.path}}/{{item3}}.gif">
				  <image wx:if="{{item3 == 'del'}}" src="../../img/wchat/icon__emotion-del.png"></image>
				  <image wx:else src="{{item.path}}/{{item3}}.gif"></image>
				</label>
			  </block>
			</view>
		  </swiper-item>
		</block>
	  </swiper>
	</view>
	</block>
	<!-- //底部表情栏 -->
	<view class="emotion__cells-footer wc__borT">
	  <scroll-view class="ul" scroll-x>
		<block wx:for="{{__emotions}}" wx:key="index">
		<view class="li {{item.selected ? 'cur' : ''}}" data-index="{{index}}" bindtap="bindSwtEmotionBar"><image src="{{item.path}}/face-lbl.gif"></image></view>
		</block>
		<view class="li"><image src="../../img/wchat/icon__emotion-set.png"></image></view>
	  </scroll-view>
	</view>
  </view>
</view>

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • vue.js聊天IM系统|聊天室|群聊

    基于vue+vuex+vue-router+webpack2.0+es6+wcPop+iconfont等技术开发的仿微信界面聊天室,之前使用h5开发过一版h5聊...

    andy2018
  • vue3全局弹框组件|vue3.0自定义插件实例

    目前市面上有些大厂已经推出了Vue3组件库,如:有赞Vant3、饿了么Element-Plus及阿里Ant-design-vue2.0,大家感兴趣的可以去看看。

    andy2018
  • h5直播webapp项目开发|h5直播案例

    很早之前就想写一个html5直播项目练练手,但是由于工作的关系,一直没有真正的开动(其实就是懒)。

    andy2018
  • 试试H3C Comware Platfo

    [H3C-GigabitEthernet0/1/0]port link-mode ?   bridge  Switch to layer2 ethernet ...

    py3study
  • 反序列化漏洞理论实战详解

    反序列化漏洞是基于序列化和反序列化的操作,在反序列化——unserialize()时存在用户可控参数,而反序列化会自动调用一些魔术方法,如果魔术方法内存在一些敏...

    litbaizhang
  • 不使用反射,“一行代码”实现Web、WinForm窗体表单数据的填充、收集、清除,和到数据库的CRUD

    问题篇:     昨天在CSDN看到这样一个帖子:“苦逼的三层代码”: 采用传统的三层架构写代码,每个数据表都要定义一个实体对象,编写后台的时候, Web层需要...

    用户1177503
  • Idea自动导入maven源码包

    赵哥窟
  • Spring事务失效的 8 大原因,这次可以吊打面试官了!

    这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。

    AI码师
  • jquery nicescroll 配置参数

    deepcc
  • 编程小知识之 JavaScript 调用堆栈

    console 支持 trace 方法,使用该方法可以向控制台输出当前的调用堆栈.

    用户2615200

扫码关注云+社区

领取腾讯云代金券