当前位置:   article > 正文

微信小程序云开发实现聊天(聊天室,一对一聊天)_基于微信小程序的聊天室

基于微信小程序的聊天室

主要使用小程序云开发的watch 监听集合中符合查询条件的数据的更新事件,支持 where, orderBy, limit,不支持 field。

一、云开发数据表设计

一个是用户表user :用户头像(avatarUrl)、昵称(nickName)等用户基本信息,可在授权登录时获取并保存到user表中。

一个是对话表存储message:发送者(from)、接受者(to)、消息(message数组)

消息利用云开发的push 之前添加到message数组中。

信息收发使用watch 根据from to查询监听消息改变

二、页面代码

chat.js

  1. const app = getApp()
  2. const { db, user } = app
  3. const User = db.collection('user')
  4. const Message = db.collection('message')
  5. const _ = db.command
  6. Page({
  7. /**
  8. * 页面的初始数据
  9. */
  10. data: {
  11. InputBottom: 0,
  12. user,
  13. to: '', // 发送给谁
  14. toInfo: {}, //接受者信息
  15. queueWatch: '',// 消息监听
  16. content: '', // 发送内容
  17. message: [], // 聊天信息
  18. scrollLast: null,
  19. },
  20. /**
  21. * 生命周期函数--监听页面加载
  22. */
  23. onLoad({ to }) {
  24. this.setData({ to })
  25. this.getToInfo()
  26. },
  27. /**
  28. * 获取接受者信息
  29. */
  30. getToInfo() {
  31. const { to } = this.data
  32. const that = this
  33. User.doc(to).get({
  34. success: ({ data }) => {
  35. that.setData({ toInfo: data })
  36. wx.setNavigationBarTitle({
  37. title: '好友:' + data.nickName,
  38. })
  39. }
  40. })
  41. },
  42. /**
  43. * 生命周期函数--监听页面显示
  44. */
  45. onShow() {
  46. const { to, user } = this.data
  47. this.handleCreate(to, user._id)
  48. this.handleWatch(true)
  49. },
  50. //消息自动到底部
  51. getScollBottom() {
  52. this.setData({ scrollLast: 'lastPosition' })
  53. },
  54. //创建聊天
  55. handleCreate(to, from, cb) {
  56. Message.where({ to, from }).get({
  57. success: ({ data }) => {
  58. if (data.length == 0) {
  59. Message.add({
  60. data: { to, from, message: [] },
  61. success: () => {
  62. (typeof cb == 'function') && cb()
  63. }
  64. })
  65. } else (typeof cb == 'function') && cb()
  66. }
  67. })
  68. },
  69. //添加信息
  70. handleAddMessage(to, from, message, cb) {
  71. Message.where({ to, from }).update({
  72. data: { message: _.push(message) },
  73. success: ({ data }) => {
  74. (typeof cb == 'function') && cb()
  75. }
  76. })
  77. },
  78. // 信息发送
  79. handleSend() {
  80. const { to, user, content } = this.data
  81. if (!content) return
  82. const from = user._id
  83. const message = { from, content }
  84. const that = this
  85. this.handleAddMessage(to, from, message, () => {
  86. console.log('添加成功')
  87. //接受者创建对话和添加信息
  88. that.handleCreate(from, to, () => {
  89. that.handleAddMessage(from, to, message, () => {
  90. that.setData({ content: '' })
  91. })
  92. })
  93. })
  94. },
  95. /**
  96. * 监听值改变
  97. */
  98. handleInput(e) {
  99. const { name, value } = app.dataset(e)
  100. const obj = {}
  101. obj[name] = value
  102. this.setData(obj)
  103. },
  104. InputFocus({ detail: { height } }) {
  105. this.setData({ InputBottom: height })
  106. },
  107. InputBlur(e) {
  108. this.setData({ InputBottom: 0 })
  109. },
  110. /**
  111. * 监听消息变化
  112. */
  113. handleWatch: async function (watch) {
  114. let { queueWatch, to, user } = this.data
  115. const that = this
  116. if (watch && !queueWatch) { // 监听
  117. queueWatch = Message.where({ to, from: user._id })
  118. .watch({// 发起监听
  119. onChange: function ({ docs }) {
  120. const { message = [] } = docs[0] || {}
  121. that.setData({ message })
  122. that.getScollBottom()
  123. },
  124. onError: function (err) {
  125. console.error('the watch closed because of error', err)
  126. }
  127. })
  128. this.setData({ queueWatch })
  129. } else if (!watch && queueWatch) { // 取消监听
  130. await queueWatch.close()
  131. this.setData({ queueWatch: '' })
  132. }
  133. },
  134. /**
  135. * 生命周期函数--监听页面卸载
  136. */
  137. onHide: function () {
  138. this.handleWatch(false) // 取消监听
  139. },
  140. /**
  141. * 页面相关事件处理函数--监听用户下拉动作
  142. */
  143. onPullDownRefresh() {
  144. },
  145. /**
  146. * 页面上拉触底事件的处理函数
  147. */
  148. onReachBottom() {
  149. },
  150. /**
  151. * 用户点击右上角分享
  152. */
  153. onShareAppMessage() {
  154. }
  155. })

chat.wxml

  1. <scroll-view style="max-height: 100vh" scroll-y="true" scroll-into-view="{{scrollLast}}">
  2. <view class="cu-chat">
  3. <block wx:for="{{message}}" wx:key="index">
  4. <!-- 自已发送的 -->
  5. <view wx:if="{{user._id==item.from}}" class="cu-item self">
  6. <view class="main">
  7. <view class="content bg-green shadow">
  8. <text>{{item.content}}</text>
  9. </view>
  10. </view>
  11. <image class="cu-avatar radius" src="{{user.avatarUrl}}"></image>
  12. <view wx:if="{{false}}" class="date">201832313:23</view>
  13. </view>
  14. <!-- 别人发送的 -->
  15. <view wx:else class="cu-item">
  16. <image class="cu-avatar radius" src="{{toInfo.avatarUrl}}"></image>
  17. <view class="main">
  18. <view class="content shadow">
  19. <text>{{item.content}}</text>
  20. </view>
  21. </view>
  22. <view wx:if="{{false}}" class="date "> 13:23</view>
  23. </view>
  24. </block>
  25. </view>
  26. <view id="lastPosition" style="height: 45px;"></view>
  27. </scroll-view>
  28. <view class="cu-bar foot input" style="bottom:{{InputBottom}}+px">
  29. <view class="action">
  30. <text class="cuIcon-comment text-grey"></text>
  31. </view>
  32. <input class="solid-bottom" value="{{content}}" data-name="content" adjust-position="false" focus="false" maxlength="300" cursor-spacing="10" bindfocus="InputFocus" bindblur="InputBlur" bindinput="handleInput"></input>
  33. <view wx:if="{{false}}" class="action">
  34. <text class="cuIcon-emojifill text-grey"></text>
  35. </view>
  36. <button class="cu-btn bg-green shadow" bindtap="handleSend">发送</button>
  37. </view>

页面样式使用的是colorui css 

三、效果

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/232559
推荐阅读
相关标签
  

闽ICP备14008679号