亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 課堂 > 小程序 > 正文

詳解微信小程序開發聊天室—實時聊天,支持圖片預覽

2020-03-21 15:56:04
字體:
來源:轉載
供稿:網友

第一次寫小程序,老板就讓我用websoket寫個聊天對話,群聊這種。第一次寫聊天功能,第一次用websoket,第一次用小程序,這是在考驗我嗎?不過我還是研究了一下,終于實現了。

首先看一下界面,界面很簡單,就是首頁剛進來獲取了用戶信息頭像,昵稱等。點擊進入聊天室就可以聊天了,下面我介紹的是前端代碼實現,后臺需要做的很簡單,就是你給他發送什么數據,他就給你返回什么數據,就是在接收前臺發送過來的圖片的時候需要做個格式轉換,因為有時候前端將接收到的json字符串轉換json對象的時候,遇到有特殊的標點符號可能會報錯,比如我就是‘/'報的錯,找了半天。

因為有人咨詢,所以附上所有小程序代碼,地址:https://github.com/chongwenwen/weixin_chat/tree/master

有人說為什么沒有utile.js的代碼,這個功能只用到websoket.js跟utile.js沒有關系哦!還有后臺代碼在頁面最底下

微信小程序,微信小程序開發,聊天室         微信小程序,微信小程序開發,聊天室

微信小程序,微信小程序開發,聊天室        微信小程序,微信小程序開發,聊天室

文檔目錄結構如下:(聊天頁面為chat)

微信小程序,微信小程序開發,聊天室  

chat.wxml頁面

首先寫好頁面結構,既然是群聊功能,肯定有自己和別人,所以頁面的view盒子應給有兩部分,一個內容左側顯示,一個內容右側顯示,下面是代碼,因為沒有正式注冊企業項目,我用的服務器都是本地的服務器,所以界面區分別人和我的聊天信息是用昵稱區分的,如果正式項目應該是由一個用戶標記去區分的

<view class="news" bindtap='outbtn'> <view class="chat-notice" wx:if="{{userInfo}}">系統消息: 歡迎 {{ userInfo.nickName }} 加入群聊</view> <view class="historycon"> <scroll-view scroll-y="true" class="history" scroll-top="{{scrollTop}}"> <block wx:for="{{newslist}}" wx:key>     <!-- 歷史消息 --> <!-- <view class="chat-news"><view style="text-align: left;padding-left: 20rpx;"><image class='new_img' src="{{item.avatarUrl? item.avatarUrl:'images/avator.png'}}"></image><text class="name">{{ item.nickName }}{{item.date}}</text></view><view class='you_left'><block wx:if="{{item.type=='text'}}"><view class='new_txt'>{{item.content}}</view></block><block wx:if="{{item.type=='image'}}"><image class="selectImg" src="{{item.images}}"></image></block></view></view> --> <view>{{item.date}}</view> <!--自己的消息 --> <view class="chat-news" wx:if="{{item.nickName == userInfo.nickName}}"> <view style="text-align: right;padding-right: 20rpx;"> <text class="name">{{ item.nickName }}</text> <image class='new_img' src="{{userInfo.avatarUrl}}"></image> </view> <view class='my_right'> <block wx:if="{{item.type=='text'}}"> <view class='new_txt'>{{item.content}}</view> </block> <block wx:if="{{item.type=='image'}}"> <image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image> </block> </view> </view> <!-- 別人的消息 --> <view class="chat-news" wx:else> <view style="text-align: left;padding-left: 20rpx;"> <image class='new_img' src="{{item.avatarUrl? item.avatarUrl:'images/avator.png'}}"></image> <text class="name">{{ item.nickName }}</text> </view> <view class='you_left'> <block wx:if="{{item.type=='text'}}"> <view class='new_txt'>{{item.content}}</view> </block> <block wx:if="{{item.type=='image'}}"> <image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image> </block> </view> </view> </block> </scroll-view> </view> </view> <view id="flag"></view> <!-- 聊天輸入 --> <view class="message"> <form bindreset="cleanInput" class="sendMessage"> <input type="text" placeholder="請輸入聊天內容.." value="{{massage}}" bindinput='bindChange'></input> <view class="add" bindtap='increase'>+</view> <button type="primary" bindtap='send' formType="reset" size="small" button-hover="blue">發送</button> </form> <view class='increased {{aniStyle?"slideup":"slidedown"}}' wx:if="{{increase}}"> <view class="image" bindtap='chooseImage'>相冊 </view> </view> </view>

websoket.js文件

在utils目錄下,是封裝了websoket的請求過程,以便在chat.js中調用。需要注意的是wx.connectSocket代表客戶端首次和服務器建立聯系,wx.onSocketOpen才是正式打開通道,wx.onSocketMessage必須在 wx.onSocketOpen 回調之后發送才生效。

wx.onSocketMessage里面帶有參數是一個函數回調,這個回調就是后臺服務器實時接收并返給前臺的數據

var url = 'ws://........';//服務器地址   function connect(user,func) { wx.connectSocket({ url: url, header:{'content-type': 'application/json'}, success: function () { console.log('信道連接成功~') }, fail: function () { console.log('信道連接失敗~') } }) wx.onSocketOpen(function (res) { wx.showToast({ title: '信道已開通~', icon: "success", duration: 2000 }) //接受服務器消息 wx.onSocketMessage(func);//func回調可以拿到服務器返回的數據 }); wx.onSocketError(function (res) { wx.showToast({ title: '信道連接失敗,請檢查!', icon: "none", duration: 2000 }) }) } //發送消息 function send(msg) { wx.sendSocketMessage({ data: msg }); } module.exports = { connect: connect, send: send }

chat.js文件

聊天室的邏輯操作頁面,websocket.connect(){}調用的是websocket.js封裝好的websoket的邏輯函數,回調就是后臺的數據,之所以在本頁面調用就是方便接收以后的邏輯操作。我建立文件的時候用的就是微信官方的快速模板生成的,所以app.js里面沒有變動,用戶在chat.js獲取userInfo的時候可以引用全局的app.globalData.userInfo

微信小程序,微信小程序開發,聊天室

 還有要注意的一點就是在選擇發送圖片的時候,必須是先把本地的圖片地址發送給后臺,轉換成服務器的圖片地址再次通過wensoket.send發送給服務器,這個時候服務器推送給其他用戶的才是正確的地址,否則你的本地地址其他用戶是訪問不到的。

// pages/chat/chat.js const app = getApp() var websocket = require('../../utils/websocket.js'); var utils = require('../../utils/util.js'); Page({   /*** 頁面的初始數據*/ data: { newslist:[], userInfo: {}, scrollTop: 0, increase:false,//圖片添加區域隱藏 aniStyle: true,//動畫效果 message:"", previewImgList:[] }, /*** 生命周期函數--監聽頁面加載*/ onLoad: function () { var that = this if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo }) } //調通接口 websocket.connect(this.data.userInfo, function (res) { // console.log(JSON.parse(res.data)) var list = [] list = that.data.newslist list.push(JSON.parse(res.data)) that.setData({ newslist: list }) }) }, // 頁面卸載 onUnload(){ wx.closeSocket(); wx.showToast({ title: '連接已斷開~', icon: "none", duration: 2000 }) }, //事件處理函數 send: function () { var flag = this if (this.data.message.trim() == ""){ wx.showToast({ title: '消息不能為空哦~', icon: "none", duration: 2000 }) }else { setTimeout(function(){ flag.setData({ increase: false }) },500) websocket.send('{ "content": "' + this.data.message + '", "date": "' + utils.formatTime(new Date()) + '","type":"text", "nickName": "' + this.data.userInfo.nickName + '", "avatarUrl": "' + this.data.userInfo.avatarUrl+'" }') this.bottom() } }, //監聽input值的改變 bindChange(res) { this.setData({ message : res.detail.value }) }, cleanInput(){ //button會自動清空,所以不能再次清空而是應該給他設置目前的input值 this.setData({ message: this.data.message }) }, increase() { this.setData({ increase: true, aniStyle: true }) }, //點擊空白隱藏message下選框 outbtn(){ this.setData({ increase: false, aniStyle: true }) }, //發送圖片 chooseImage() { var that = this wx.chooseImage({ count: 1, // 默認9 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function (res) { // 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片 var tempFilePaths = res.tempFilePaths // console.log(tempFilePaths) wx.uploadFile({ url: 'http://.....', //服務器地址 filePath: tempFilePaths[0], name: 'file', headers: { 'Content-Type': 'form-data' }, success: function (res) { if (res.data){ that.setData({ increase: false }) websocket.send('{"images":"'+ res.data +'","date":"'+utils.formatTime(new Date())+'","type":"image","nickName":"'+that.data.userInfo.nickName+'","avatarUrl":"'+that.data.userInfo.avatarUrl+'"}') that.bottom() } } }) } }) }, //圖片預覽 previewImg(e){ var that = this //必須給對應的wxml的image標簽設置data-set=“圖片路徑”,否則接收不到 var res = e.target.dataset.src var list = this.data.previewImgList //頁面的圖片集合數組 //判斷res在數組中是否存在,不存在則push到數組中, -1表示res不存在 if (list.indexOf(res) == -1 ) { this.data.previewImgList.push(res) } wx.previewImage({ current: res, // 當前顯示圖片的http鏈接 urls: that.data.previewImgList // 需要預覽的圖片http鏈接列表 }) }, //聊天消息始終顯示最底端 bottom: function () { var query = wx.createSelectorQuery() query.select('#flag').boundingClientRect() query.selectViewport().scrollOffset() query.exec(function (res) { wx.pageScrollTo({ scrollTop: res[0].bottom // #the-id節點的下邊界坐標 }) res[1].scrollTop // 顯示區域的豎直滾動位置 }) }, })

最后是頁面的樣式文件chat.wxss

/* pages/chat/chat.wxss */ page { background-color: #f7f7f7; height: 100%; } /* 聊天內容 */ .news { padding-top: 30rpx; text-align: center; /* height:100%; */ box-sizing:border-box; } #flag{ margin-bottom: 100rpx; height: 30rpx; } .chat-notice{ text-align: center; font-size: 30rpx; padding: 10rpx 0; color: #666; } .historycon { height: 100%; width: 100%; /* flex-direction: column; */ display: flex; border-top: 0px; } /* 聊天 */ .chat-news{ width: 100%; overflow: hidden; } .chat-news .my_right { float: right; /* right: 40rpx; */ padding: 10rpx 10rpx; } .chat-news .name{ margin-right: 10rpx; } .chat-news .you_left { float: left; /* left: 5rpx; */ padding: 10rpx 10rpx; } .selectImg{ display: inline-block; width: 150rpx; height: 150rpx; margin-left: 50rpx; } .my_right .selectImg{ margin-right: 80rpx; } .new_img { width: 60rpx; height: 60rpx; border-radius: 50%; vertical-align: middle; margin-right: 10rpx; } .new_txt { max-width: 300rpx; display: inline-block; border-radius: 6rpx; line-height: 60rpx; background-color: #95d4ff; padding: 5rpx 20rpx; margin: 0 10rpx; margin-left: 50rpx; } .my_right .new_txt{ margin-right:60rpx; } .you{ background-color: lightgreen; } .my { border-color: transparent transparent transparent #95d4ff; } .you { border-color: transparent #95d4ff transparent transparent; } .hei{ margin-top: 50px; height: 20rpx; } .history { height: 100%; margin-top: 15px; padding: 10rpx; font-size: 14px; line-height: 40px; word-break: break-all; } ::-webkit-scrollbar { width: 0; height: 0; color: transparent; z-index: -1; }   /* 信息輸入區域 */ .message{ position: fixed; bottom:0; width: 100%; } .sendMessage{ display: block; height: 80rpx; padding: 10rpx 10rpx; background-color: #fff; border-top: 2rpx solid #eee; border-bottom: 2rpx solid #eee; z-index:3; } .sendMessage input{ float:left; width: 66%; height: 100%; line-height: 80rpx; border-bottom: 1rpx solid #ccc; padding:0 10rpx; font-size: 35rpx; color: #666; } .sendMessage view{ display: inline-block; width: 80rpx; height: 80rpx; line-height: 80rpx; font-size: 60rpx; text-align: center; color: #999; border: 1rpx solid #ccc; border-radius: 50%; margin-left: 10rpx; } .sendMessage button { float: right; font-size: 35rpx; } .increased{ width:100%; /* height: 150rpx; */ padding: 40rpx 30rpx; background-color: #fff; } .increased .image{ width: 100rpx; height: 100rpx; border: 3rpx solid #ccc; line-height: 100rpx; text-align: center; border-radius: 8rpx; font-size:35rpx; } @keyframes slidedown { from { transform: translateY(0); } to { transform: translateY(100%); } } .slidedown { animation: slidedown 0.5s linear ; } .slideup { animation: slideup 0.5s linear ; } @keyframes slideup { from { transform: translateY(100%); } to { transform: translateY(0); } }

后臺代碼(圖片):

微信小程序,微信小程序開發,聊天室

以上所述是小編給大家介紹的微信小程序實時聊天支持圖片預覽詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網網站的支持!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97国产精品人人爽人人做| 色偷偷噜噜噜亚洲男人的天堂| 亚洲精品网址在线观看| 欧美性生交大片免费| 久久精品国产亚洲一区二区| 国产精品国产福利国产秒拍| 亚洲色图50p| 精品亚洲永久免费精品| 欧美国产欧美亚洲国产日韩mv天天看完整| 精品视频在线播放色网色视频| 亚洲国产高清福利视频| 亚洲综合自拍一区| 欧美成aaa人片在线观看蜜臀| 夜夜嗨av色综合久久久综合网| 在线播放日韩欧美| 精品国产一区二区三区在线观看| 中文字幕日韩专区| 日韩欧美高清视频| 成人激情综合网| 亚洲黄色www| 亚洲成av人影院在线观看| 97视频在线观看视频免费视频| 亚洲va欧美va国产综合久久| 亚洲老板91色精品久久| 久久视频精品在线| 精品高清美女精品国产区| 日韩中文字幕视频在线观看| 亚洲精品国产精品自产a区红杏吧| 欧美午夜xxx| 国产精品久久久久久久久久免费| 亚洲香蕉av在线一区二区三区| 欧美福利在线观看| 欧美乱人伦中文字幕在线| 亚洲精品在线看| 黄色精品在线看| 97人人爽人人喊人人模波多| 精品视频久久久久久久| 精品亚洲一区二区三区| 国产欧美在线视频| 国产欧美一区二区三区在线看| 91久久嫩草影院一区二区| 日韩中文在线中文网三级| 精品久久久久久久久久| 亚洲第五色综合网| 亚洲男人的天堂在线| 蜜月aⅴ免费一区二区三区| 日韩乱码在线视频| 亚洲天堂男人天堂女人天堂| 欧美一区三区三区高中清蜜桃| 亚洲第一天堂无码专区| 久久久成人av| 成人午夜在线观看| 91精品国产高清久久久久久91| 久久久久女教师免费一区| 日韩精品久久久久久福利| 中文国产成人精品久久一| 欧美国产日韩免费| 欧美国产日韩一区二区三区| 欧美黑人一区二区三区| 国产欧美日韩91| 国产精品丝袜视频| 久久久久久久亚洲精品| 午夜欧美大片免费观看| 亚洲美女在线看| 久久亚洲精品中文字幕冲田杏梨| 亚洲第一综合天堂另类专| 亚洲免费人成在线视频观看| 国产精品美女www爽爽爽视频| 日韩av不卡在线| 精品国产一区二区三区久久久狼| 日韩女在线观看| 国产成人精品免费久久久久| 久久精品成人动漫| 国产成人精品久久久| 91国产一区在线| 正在播放欧美一区| 亚洲国产中文字幕在线观看| 精品一区二区三区四区| 亚洲在线第一页| 国产精品久久久久福利| 国产精品极品尤物在线观看| 日韩亚洲欧美中文在线| 欧美激情综合色综合啪啪五月| 奇米4444一区二区三区| 成人黄色av网站| 欧美在线视频观看免费网站| 亚洲缚视频在线观看| 日韩国产精品视频| 亚洲成色777777在线观看影院| 日韩欧美一区二区在线| 国产精品一区二区性色av| 色黄久久久久久| 国产午夜精品视频免费不卡69堂| 91av在线看| 久久亚洲综合国产精品99麻豆精品福利| 国产欧美日韩综合精品| 久久97久久97精品免视看| 伊人激情综合网| 成人免费高清完整版在线观看| 亚洲午夜久久久久久久| 国产午夜精品理论片a级探花| 色婷婷综合久久久久| 亚洲香蕉成人av网站在线观看| 91亚洲一区精品| 国产亚洲视频在线| 亚洲福利精品在线| 国产精品网红直播| 国模精品视频一区二区| 久久久久99精品久久久久| 91精品国产91久久久久久久久| 国产啪精品视频网站| 国产精品麻豆va在线播放| 韩剧1988在线观看免费完整版| 97精品国产97久久久久久免费| 亚洲一区制服诱惑| 欧美精品九九久久| 亚洲精品91美女久久久久久久| 色吧影院999| 国产色视频一区| 欧美亚洲一级片| 隔壁老王国产在线精品| 国产欧美韩国高清| 国产精品99久久久久久白浆小说| 浅井舞香一区二区| 韩剧1988在线观看免费完整版| 成人乱人伦精品视频在线观看| 91在线视频九色| 日本亚洲精品在线观看| 亚洲人午夜色婷婷| 国产一区二区三区在线观看视频| 欧美中文字幕在线播放| 久久99国产综合精品女同| 久热精品在线视频| 欧美在线视频一区二区| 亚洲第一免费播放区| 精品国产乱码久久久久久虫虫漫画| 成人综合国产精品| 在线播放国产精品| 欧美日韩免费区域视频在线观看| 日韩大陆毛片av| 久久人人爽人人爽爽久久| 日韩欧美成人免费视频| 欧美黑人巨大精品一区二区| 国外视频精品毛片| 国产精品久久久久久久久久久不卡| 亚洲一区亚洲二区| 精品久久久久久亚洲国产300| 国产噜噜噜噜噜久久久久久久久| 91精品久久久久久久久久另类| 欧美中文字幕视频| 亚洲精品视频网上网址在线观看| 欧美日韩国产中文精品字幕自在自线| 中文字幕日韩有码| 欧美日韩国产综合视频在线观看中文| 亚洲乱码av中文一区二区| 亚洲jizzjizz日本少妇| 欧美与欧洲交xxxx免费观看| 欧美午夜视频一区二区| 精品伊人久久97| 精品国产精品自拍| 韩国视频理论视频久久| 亚洲三级av在线| 久久男人av资源网站| 亚洲理论片在线观看|