uniapp模仿微信實現聊天界面的示例代碼
項目演示
前言
我是看B站的視頻一個一個敲的,講的還不錯。可以去看看vue+node.js即時通訊聊天室APP開發前端篇
主界面
chat.vue
<template> <!-- 聊天界面展示https://www.bilibili.com/video/BV1hT4y1P75N?p=22 搭建1和2 --> <view class="content"> <!-- 聊天內容 --> <scroll-view class="chat" scroll-y="true" scroll-with-animation="true" :scroll-into-view="scrollToView"> <view class="chat-main" :style="{paddingBottom:inputh+'px'}"> <view class="chat-ls" v-for="(item,index) in unshiftmsg" :key="index" :id="'msg'+ index"> <view class="chat-time" v-if="item.createTime != ''">{{changeTime(item.createTime)}}</view> <view class="msg-m msg-left" v-if="item.sendName == friendName"> <image class="user-img" src="../../../static/logo.png"></image> <view class="message" v-if="item.TextType == 0"> <!-- 文字 --> <view class="msg-text">{{item.sendText}}</view> </view> <view class="message" v-if="item.TextType == 1" @tap="previewImg(item.sendText)"> <!-- 圖像 --> <image :src="item.sendText" class="msg-img" mode="widthFix"></image> </view> <view class="message" v-if="item.TextType == 2" @tap="playVoice(item.sendText.voice)"> <!-- 音頻 --> <view class="msg-text voice" :style="{width:item.sendText.time*4+'rpx'}"> <image src="../../../static/icon/Hotline.png" class="voice-img"></image> {{item.sendText.time}}″ </view> </view> <view class="message" v-if="item.TextType == 3" @tap="openLocation(item.sendText)"> <!-- 位置 --> <view class="msg-map"> <view class="map-name">{{item.sendText.name}}</view> <view class="map-address">{{item.sendText.address}}</view> <!-- 如果map不起作用,就可以直接用一張圖片去替代 --> <map class="map" :longitude="item.sendText.longitude" :latitude="item.sendText.latitude" :markers="covers(item.sendText)"></map> </view> </view> </view> <view class="msg-m msg-right" v-if="item.sendName != friendName"> <image class="user-img" src="../../../static/logo.png"></image> <view class="message" v-if="item.TextType == 0"> <view class="msg-text">{{item.sendText}}</view> </view> <view class="message" v-if="item.TextType == 1" @tap="previewImg(item.sendText)"> <image :src="item.sendText" class="msg-img" mode="widthFix"></image> </view> <view class="message" v-if="item.TextType == 2" @tap="playVoice(item.sendText.voice)"> <!-- 音頻 --> <view class="msg-text voice" :style="{width:item.sendText.time*4+'rpx'}"> {{item.sendText.time}}″ <image src="../../../static/icon/Hotline.png" class="voice-img"></image> </view> </view> <view class="message" v-if="item.TextType == 3" @tap="openLocation(item.sendText)"> <!-- 位置 --> <view class="msg-map"> <view class="map-name">{{item.sendText.name}}</view> <view class="map-address">{{item.sendText.address}}</view> <map class="map" :longitude="item.sendText.longitude" :latitude="item.sendText.latitude" :markers="covers(item.sendText)"></map> </view> </view> </view> </view> </view> </scroll-view> <submit @inputs="inputs" @heights="heights"></submit> </view> </template> <script> import dateTime from '../../../common/dateTime.js'; import submit from '../../../components/submit/submit.vue'; //音頻播放 const innerAudioContext = uni.createInnerAudioContext(); export default { data() { return { friendName: "xpq", msg: [{ "sendName": "xpq", "receviceName": "゛時光い", "sendText": { "address": "湖南省嶽陽市湘陰縣新世紀大道", "latitude": 28.68925, "longitude": 112.90917, "name": "湘陰縣政府(新世紀大道北)", }, "createTime": "2022-01-06 12:40:12", "updateTime": null, "chatmState": 1, "TextType": 3 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": { "voice": "時光匆匆流過", "time": 2 //秒 }, "createTime": "2022-01-06 12:22:12", "updateTime": null, "chatmState": 1, "TextType": 2 }, { "sendName": "xpq", "receviceName": "゛時光い", "sendText": { "voice": "謝謝你", "time": 60 //秒 }, "createTime": "2022-01-06 12:00:12", "updateTime": null, "chatmState": 1, "TextType": 2 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "這是第九條未讀消息", "createTime": "2022-01-03 12:22:12", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "這是第八條未讀消息", "createTime": "2022-01-02 12:22:07", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "xpq", "receviceName": "xpq", "sendText": "這是第七條未讀消息", "createTime": "2021-12-19 12:22:03", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "這是第六條未讀消息", "createTime": "2021-12-19 12:21:58", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "http://demo.rageframe.com/attachment/images/2021/11/18/image_1637224530_diIlZlmm.jpeg", "createTime": "2021-12-19 12:21:54", "updateTime": null, "chatmState": 1, "TextType": 1 }, { "sendName": "xpq", "receviceName": "゛時光い", "sendText": "http://demo2.rageframe.com/attachment/images/2021/09/01/image_1630483477_N03W37zs.jpg", "createTime": "2021-12-19 12:21:48", "updateTime": null, "chatmState": 1, "TextType": 1 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "這是第三條未讀消息", "createTime": "2021-12-19 12:21:42", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "這是第二條未讀消息", "createTime": "2021-12-19 12:21:33", "updateTime": null, "chatmState": 1, "TextType": 0 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "http://demo2.rageframe.com/attachment/images/2021/09/01/image_1630483477_N03W37zs.jpg", "createTime": "2021-12-19 11:02:18", "updateTime": null, "chatmState": 1, "TextType": 1 }, { "sendName": "゛時光い", "receviceName": "xpq", "sendText": "愛你啊", "createTime": "2021-12-18 20:37:03", "updateTime": null, "chatmState": 0, "TextType": 0 } ], // 反轉數據接收 unshiftmsg: [], imgMsg: [], scrollToView: '', oldTime: new Date(), inputh: '60' } }, onShow() { // 數組倒敘 主要是應對後端傳過來的數據 for (var i = 0; i < this.msg.length; i++) { //時間間隔處理 if (i < this.msg.length - 1) { //這裡表示頭部時間還是顯示一下 let t = dateTime.spaceTime(this.oldTime, this.msg[i].createTime); if (t) { this.oldTime = t; } this.msg[i].createTime = t; } // 獲取圖片,為下面的預覽做準備 if (this.msg[i].TextType == 1) { this.imgMsg.unshift(this.msg[i].sendText) } this.unshiftmsg.unshift(this.msg[i]); } // 跳轉到最後一條數據 與前面的:id進行對照 this.$nextTick(function() { this.scrollToView = 'msg' + (this.unshiftmsg.length - 1) }) }, components: { submit, }, methods: { changeTime(date) { return dateTime.dateTime1(date); }, // 進行圖片的預覽 previewImg(e) { let index = 0; for (let i = 0; i < this.imgMsg.length; i++) { if (this.imgMsg[i] == e) { index = i; } } console.log("index", index) // 預覽圖片 uni.previewImage({ current: index, urls: this.imgMsg, longPressActions: { itemList: ['發送給朋友', '保存圖片', '收藏'], success: function(data) { console.log('選中瞭第' + (data.tapIndex + 1) + '個按鈕,第' + (data.index + 1) + '張圖片'); }, fail: function(err) { console.log(err.errMsg); } } }); }, //音頻播放 playVoice(e) { innerAudioContext.src = e; innerAudioContext.onPlay(() => { console.log('開始播放'); }); }, //地圖定位 covers(e) { let map = [{ latitude: e.latitude, longitude: e.longitude, iconPath: '../../../static/logo.png' }] return (map); }, //跳轉地圖信息 openLocation(e) { uni.openLocation({ latitude: e.latitude, longitude: e.longitude, name: e.name, address: e.address, success: function() { console.log('success'); } }); }, //接受輸入內容 inputs(e) { //時間間隔處理 let data = { "sendName": "゛時光い", "receviceName": "xpq", "sendText": e.message, "createTime": new Date(), "updateTime": new Date(), "chatmState": 1, "TextType": e.type }; // 發送給服務器消息 // onSendWS(JSON.stringify(data)); this.unshiftmsg.push(data); // 跳轉到最後一條數據 與前面的:id進行對照 this.$nextTick(function() { this.scrollToView = 'msg' + (this.unshiftmsg.length - 1) }) if (e.type == 1) { this.imgMsg.push(e.message); } console.log(e) }, //輸入框高度 heights(e) { console.log("高度:", e) this.inputh = e; this.goBottom(); }, // 滾動到底部 goBottom() { this.scrollToView = ''; this.$nextTick(function() { this.scrollToView = 'msg' + (this.unshiftmsg.length - 1) }) } } } </script> <style lang="scss"> page { height: 100%; } .content { height: 100%; background-color: rgba(244, 244, 244, 1); } .chat { height: 100%; .chat-main { padding-left: 32rpx; padding-right: 32rpx; padding-top: 20rpx; // padding-bottom: 120rpx; //獲取動態高度 display: flex; flex-direction: column; } .chat-ls { .chat-time { font-size: 24rpx; color: rgba(39, 40, 50, 0.3); line-height: 34rpx; padding: 10rpx 0rpx; text-align: center; } .msg-m { display: flex; padding: 20rpx 0; .user-img { flex: none; width: 80rpx; height: 80rpx; border-radius: 20rpx; } .message { flex: none; max-width: 480rpx; } .msg-text { font-size: 32rpx; color: rgba(39, 40, 50, 1); line-height: 44rpx; padding: 18rpx 24rpx; } .msg-img { max-width: 400rpx; border-radius: 20rpx; } .msg-map { background: #fff; width: 464rpx; height: 284rpx; overflow: hidden; .map-name { font-size: 32rpx; color: rgba(39, 40, 50, 1); line-height: 44rpx; padding: 18rpx 24rpx 0 24rpx; //下面四行是單行文字的樣式 display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; } .map-address { font-size: 24rpx; color: rgba(39, 40, 50, 0.4); padding: 0 24rpx; //下面四行是單行文字的樣式 display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; } .map { padding-top: 8rpx; width: 464rpx; height: 190rpx; } } .voice { // width: 200rpx; min-width: 100rpx; max-width: 400rpx; } .voice-img { width: 28rpx; height: 36rpx; } } .msg-left { flex-direction: row; .msg-text { margin-left: 16rpx; background-color: #fff; border-radius: 0rpx 20rpx 20rpx 20rpx; } .ms-img { margin-left: 16rpx; } .msh-map { margin-left: 16rpx; border-radius: 0rpx 20rpx 20rpx 20rpx; } .voice { text-align: right; } .voice-img { float: left; transform: rotate(180deg); width: 28rpx; height: 36rpx; padding-bottom: 4rpx; } } .msg-right { flex-direction: row-reverse; .msg-text { margin-right: 16rpx; background-color: rgba(255, 228, 49, 0.8); border-radius: 20rpx 0rpx 20rpx 20rpx; } .ms-img { margin-right: 16rpx; } .msh-map { margin-left: 16rpx; border-radius: 20rpx 0rpx 20rpx 20rpx; } .voice { text-align: left; } .voice-img { float: right; padding: 4rpx; width: 28rpx; height: 36rpx; } } } } </style>
chat.vue中引入的js文件
dateTime.js
export default{ //首頁時間轉化 dateTime(e){ let old = new Date(e); let now = new Date(); //獲取old具體時間 let d = old.getTime(); let h = old.getHours(); let m = old.getMinutes(); let Y = old.getFullYear(); let M = old.getMonth()+1; let D = old.getDate(); //獲取now具體時間 let nd =now.getTime(); let nh = now.getHours(); let n = now.getMinutes(); let nY = now.getFullYear(); let nM = now.getMonth()+1; let nD = now.getDate(); //當天的時間 if(D === nD && M === nM && Y === nY){ if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return h+':'+m; } //昨天時間 if(D+1 === nD && M === nM && Y === nY){ if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return '昨天 '+h+':'+m; }else{ //大於兩天 return Y+'/'+M+'/'+D; } }, //聊天時,發送時間處理 dateTime1(e){ let old = new Date(e); let now = new Date(); //獲取old具體時間 let d = old.getTime(); let h = old.getHours(); let m = old.getMinutes(); let Y = old.getFullYear(); let M = old.getMonth()+1; let D = old.getDate(); //獲取now具體時間 let nd =now.getTime(); let nh = now.getHours(); let n = now.getMinutes(); let nY = now.getFullYear(); let nM = now.getMonth()+1; let nD = now.getDate(); //當天的時間 if(D === nD && M === nM && Y === nY){ if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return h+':'+m; } //昨天時間 if(D+1 === nD && M === nM && Y === nY){ if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return '昨天 '+h+':'+m; }else if( Y == nY){ //今年 if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return M+'月'+D+'日 '+h+':'+m }else{ //大於今年 if(h<10){ h = '0'+h; } if(m<10){ m = '0'+m; } return Y+'年'+ M +'月' +D+ '日 '+h+':'+m } }, // 間隔時間差 spaceTime(old,now){ old = new Date(old); now = new Date(now); var told = old.getTime(); var tnow = now.getTime(); if(told > (tnow+1000*60*5)){ return now; }else{ return ''; } } }
chat.vue中引入的組件
submit.vue
<template> <view> <view class="submit"> <view class="submit-chat"> <view class="bt-img" @tap="records"> <image :src="toc"></image> </view> <!-- 文本框 --> <textarea auto-height="true" class="chat-send btn" :class="{displaynone:isrecord}" @input="inputs" @focus="focus" v-model="msg"></textarea> <view class="record btn" :class="{displaynone:!isrecord}" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove"> 按住說話 </view> <view class="bt-img" @tap="emoji"> <image src="../../static/icon/commonproblem.png"></image> </view> <view class="bt-img" @tap="more"> <image src="../../static/icon/news.png"></image> </view> </view> <!-- 表情 --> <view class="emoji" :class="{displaynone:!isemoji}"> <view class="emoji-send"> <view class="emoji-send-det" @tap="emojiBack"> <image src="../../static/icon/leftbrackets.png"></image> </view> <view class="emoji-send-bt" @tap="emojiSend">發送</view> </view> <emoji @emotion="emotion" :height="260"></emoji> </view> <!-- 更多 --> <view class="more" :class="{displaynone:!ismore}"> <view class="more-list" @tap="sendImg('album')"> <image src="../../static/icon/noreceive.png"></image> <view class="more-list-title">圖片</view> </view> <view class="more-list" @tap="sendImg('camera')"> <image src="../../static/icon/noreceive.png"></image> <view class="more-list-title">拍照</view> </view> <view class="more-list" @tap="choseLocation"> <image src="../../static/icon/noreceive.png"></image> <view class="more-list-title">定位</view> </view> <view class="more-list"> <image src="../../static/icon/noreceive.png"></image> <view class="more-list-title">視頻</view> </view> <view class="more-list"> <image src="../../static/icon/noreceive.png"></image> <view class="more-list-title">文件</view> </view> </view> </view> <view class="voice-bg" :class="{displaynone:!voicebg}"> <view class="voice-bg-len"> <view class="voice-bg-time" :style="{width:vlength/0.6+'%'}"> {{vlength}}″ </view> <view class="voice-del">上滑取消錄音</view> </view> </view> </view> </template> <script> // 引入組件 import emoji from '../emoji/emoji.vue' // 錄音 const recorderManager = uni.getRecorderManager(); export default { data() { return { isrecord: false, isemoji: false, ismore: false, voicebg: false, pageY: 0, msg: "", // 直接引用地址可能出不來,需要用require toc: require('../../static/icon/allorder.png'), timer: '', //計時器 vlength: 0 }; }, components: { emoji, }, methods: { //獲取高度方法 getElementHeight() { const query = uni.createSelectorQuery().in(this); query.select('.submit').boundingClientRect(data => { this.$emit('heights', data.height); }).exec(); }, //切換音頻 records() { //切換的時候關閉其他界面 this.ismore = false this.isemoji = false //切換高度 setTimeout(() => { this.getElementHeight(); }, 10) if (this.isrecord) { this.isrecord = false; this.toc = require("../../static/icon/allorder.png"); } else { this.isrecord = true; this.toc = require("../../static/icon/wechat.png"); } }, // 表情 emoji() { this.isemoji = !this.isemoji; //切換的時候關閉其功能 this.ismore = false this.isrecord = false; this.toc = require("../../static/icon/allorder.png"); //切換高度 setTimeout(() => { this.getElementHeight(); }, 10) }, //接收表情 emotion(e) { console.log(e), this.msg = this.msg + e }, //文字發送 inputs(e) { var chatm = e.detail.value; var pos = chatm.indexOf('\n'); // 檢索字符串沒有數據,返回-1 // if (pos != -1 && chatm.length > 1) { // this.$emit('inputs', this.msg); // setTimeout(() => { // this.msg = ''; // }, 0) // } if (pos != -1 && chatm.length > 1) { // 0為表情和文字 this.send(this.msg, 0) } }, // 輸入框聚焦 focus() { //關閉其他項 this.isemoji = false; this.ismore = false; setTimeout(() => { this.getElementHeight() }, 10) }, // 表情內發送 emojiSend() { // if (this.msg.length > 0) { // this.$emit('inputs', this.msg); // setTimeout(() => { // this.msg = ''; // }, 0) // } if (this.msg.length > 0) { //0為表情和文字 this.send(this.msg, 0) } }, // 表格退格 emojiBack() { if (this.msg.length > 0) { this.msg = this.msg.substring(0, this.msg.length - 1); } }, //更多功能 more() { this.ismore = !this.ismore; //切換的時候關閉其他界面 this.isemoji = false this.isrecord = false; this.toc = require("../../static/icon/allorder.png"); setTimeout(() => { this.getElementHeight(); }, 10) }, //圖片發送 sendImg(e) { let count = 9; if (e == 'album') { count = 9; } else { count = 1; } uni.chooseImage({ count: count, //默認9 sizeType: ['original', 'compressed'], //可以指定是原圖還是壓縮圖,默認二者都有 sourceType: [e], //從相冊選擇 // success: function (res) { //用function的方式會找不到send方法 success: (res) => { console.log(JSON.stringify(res.tempFilePaths)); const filePaths = res.tempFilePaths; for (let i = 0; i < filePaths.length; i++) { this.send(filePaths[i], 1) } } }); }, //音頻處理 //開始錄音 touchstart(e) { console.log("開始錄音") console.log("點擊產生數據", e) this.pageY = e.changedTouches[0].pageY; this.voicebg = true; let i = 1; this.timer = setInterval(() => { this.vlength = i; i++; console.log("計時器開始工作,第幾秒", i) //結束計時 if (i > 60) { clearInterval(this.timer); this.touchend(); } }, 1000) recorderManager.start(); }, //刪除錄音 touchmove(e) { // console.log("滑動到的y軸高度:",e.changedTouches[0].pageY); if (this.pageY - e.changedTouches[0].pageY > 100) { // 關閉錄音界面 this.voicebg = false; } }, // 結束錄音 touchend() { console.log("結束錄音") clearInterval(this.timer); recorderManager.stop(); // recorderManager.onStop(function(res) { recorderManager.onStop((res) => { let data = { voice: res.tempFilePath, time: this.vlength } if (this.voicebg) { this.send(data, 2); } // //時長歸位 this.vlength = 0; this.voicebg = false; console.log('recorder stop' + JSON.stringify(res)); // self.voicePath = res.tempFilePath; }); }, //獲取位置 choseLocation() { uni.chooseLocation({ // success: function(res) { success: res => { let data = { name: res.name, address: res.address, latitude: res.latitude, longitude: res.longitude } this.send(data, 3); // console.log('位置名稱:' + res.name); // console.log('詳細地址:' + res.address); // console.log('緯度:' + res.latitude); // console.log('經度:' + res.longitude); } }); }, //發送 send(msg, type) { let date = { message: msg, type: type } this.$emit('inputs', date); setTimeout(() => { this.msg = ''; }, 0) } } }; </script> <style lang="scss" scoped> .submit { background: rgba(244, 244, 244, 0.96); border-top: 1px solid rgba(39, 40, 50, 0.1); width: 100%; position: fixed; bottom: 0; z-index: 100; // padding-bottom: var(--status-bar-height); padding-bottom: env(safe-area-inset-bottom); } .displaynone { display: none; } .submit-chat { width: 100%; display: flex; align-items: flex-end; box-sizing: border-box; padding: 14rpx 14rpx; image { width: 56rpx; height: 56rpx; margin: 0 10rpx; flex: auto; } .btn { flex: auto; background-color: #fff; border-radius: 10rpx; padding: 20rpx; max-height: 160rpx; margin: 0 10rpx; } .chat-send { line-height: 44rpx; } .record { line-height: 44rpx; text-align: center; font-size: 20rpx; color: rgba(39, 40, 50, 0.6); } } .emoji { width: 100%; height: 460rpx; background: rgba(236, 237, 238, 1); box-shadow: 0px 11rpx 0px 0px rgba(0, 0, 0, 0.1); .emoji-send { width: 280rpx; height: 104rpx; padding-top: 24rpx; background-color: rgba(236, 237, 238, 0.8); position: fixed; // bottom: 0; bottom: env(safe-area-inset-bottom); right: 0; display: flex; .emoji-send-bt { flex: 1; margin: 0 32rpx 0 20rpx; height: 80rpx; background: rgba(255, 228, 49, 1); font-size: 32rpx; text-align: center; line-height: 80rpx; border-radius: 12rpx; } .emoji-send-det { flex: 1; margin-left: 24rpx; height: 80rpx; background: #fff; font-size: 32rpx; text-align: center; line-height: 80rpx; border-radius: 12rpx; image { width: 42rpx; height: 32rpx; } } } } .more { width: 100%; height: 436rpx; background: rgba(236, 237, 238, 1); box-shadow: 0px 11rpx 0px 0px rgba(0, 0, 0, 0.1); bottom: env(safe-area-inset-bottom); padding: 8rpx 20rpx; box-sizing: border-box; .more-list { width: 25%; text-align: center; float: left; padding-top: 32rpx; image { width: 72rpx; height: 72rpx; padding: 24rpx; background: rgba(255, 255, 255, 1); border-radius: 24rpx; } .more-list-title { font-size: 24rpx; color: rgba(39, 40, 50, 0.5); line-height: 34rpx; } } } .voice-bg { height: 100%; width: 100%; background-color: rgba(0, 0, 0, 0.3); position: fixed; top: 0; bottom: 0; z-index: 1001; .voice-bg-len { height: 84rpx; width: 600rpx; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; background-color: rgba(255, 255, 255, 0.2); border-radius: 42rpx; text-align: center; } .voice-bg-time { display: inline-block; min-width: 120rpx; line-height: 84rpx; background-color: rgba(255, 228, 49, 1); border-radius: 42rpx; } .voice-del { position: absolute; bottom: -480rpx; width: 100%; text-align: center; color: #fff; font-size: 28rpx; } } </style>
submit.vue中引入的組件
emoji.vue
<template> <view class="emoji" :style="{height:height+'px'}"> <view class="emoji-line" v-for="(line,i) in emoji" :key="i"> <view class="emoji-line-item" v-for="(item,index) in line" :key="index" @tap="clickEmoji(item)">{{item}} </view> </view> </view> </template> <script> export default { props:{ height:{ type:Number, default:260 } }, name: "emoji", data() { return { emoji: [ ['😀', '😁', '😂', '🤣', '😃', '😃', '😅'], ['😄', '😆', '😉', '😊', '😋', '😎', '😍'], ['😎', '😘', '😗', '😙', '🙂', '🤗', '😑'], ['😏', '😣', '😥', '😮', '🤐', '😯', '😶'], ['😪', '😫', '😴', '😌', '😛', '🤤', '🙄'], ['😒', '😓', '😕', '🙃', '🤑', '🙁', '😚'], ['😖', '😤', '😭', '😨', '😰', '😬', '😵'], ['😱', '😡', '😷', '💀', '👻', '💍', '💄'], ['💩', '👑', '🎓', '👀', '💪🏻', '☝🏻', '✌🏼'], ['🤘🏻', '🤙🏼', '👌🏻', '✊🏻', '👍🏼', '👎🏻', '👏🏻'], ['🙏🏻', '🤝', '🍖', '🍲', '🍦', '🍰'] //'🍔', ] }; }, methods: { clickEmoji(e) { this.$emit('emotion', e) } } } </script> <style lang="scss"> .emoji { width: 100%; // height: 460rpx; padding: 16rpx 10rpx 130rpx 10rpx; box-sizing: border-box; overflow: hidden; overflow-y: auto; .emoji-line{ display: flex; .emoji-line-item { flex: 1; text-align: center; font-size: 44rpx; line-height: 140rpx; } } } </style>
最後
很多靜態圖片圖片都是本地的,需要各位用自己的本地圖片代替。
以上就是uniapp模仿微信實現聊天界面的示例代碼的詳細內容,更多關於uniapp仿微信聊天界面的資料請關註WalkonNet其它相關文章!