因為融云含ui的聊天室并不適用于uniapp切厘,所以uniapp中所有東西就需要自己來實現(xiàn),好在融云給的接口還是很全的等浊,因為項目的差異性我只介紹聊天室的代碼(因為沒做任何優(yōu)化屯曹,可能代碼可讀性并不強(qiáng),而且只實現(xiàn)了發(fā)送文字信息的功能吓坚,分享出來只是方便自己看撵幽,接不通可以私信我)
在開始聊天之前需要先連接融云的im(main.js中)
//引入融云SDK
const RongIMib = require('./common/libs/RongIMLib-3.0.7.1-dev.js')
const RongIMLib = require('./common/libs/RongEmoji-2.2.9.js')
//初始化融云SDK
let im = RongIMib.init({
appkey: ""http://申請的key
})
Vue.prototype.$Im = im
//掛載融云到Vue原型
Vue.prototype.$RongIMib = RongIMib
Vue.prototype.$RongIMLib=RongIMLib
可以在首頁打印下判斷是否連接成功
我是在首頁連接的融云,連接的話只一次就可以礁击,可以在登錄成功后連接盐杂,我感覺在登錄成功后連接更好(剛開始就連接就好,不用監(jiān)聽哆窿,在會話列表里已經(jīng)監(jiān)聽過了) 注意:連接融云需要token链烈,這時候需要讀后端的接口拿到
rongyunInit() {
//初始化融云
// let _that = this;
//設(shè)置監(jiān)聽
// let conversationList = []; //當(dāng)前存在的會話列表
// _that.$Im.watch({
// //對會話列表進(jìn)行監(jiān)聽
// conversation: event => {
// console.log(event);
// let updatedConversationList = event.updatedConversationList; //更新的會話列表
// console.log('upload:', updatedConversationList);
// let sendOut = {
// content: event.updatedConversationList[0].latestMessage.content.content,
// sentTime: event.updatedConversationList[0].latestMessage.sentTime
// };
// uni.setStorageSync('sendOut', sendOut);
// if (event.updatedConversationList[0].latestMessage.messageDirection == 2) {
// this.chat.push({
// type: event.updatedConversationList[0].latestMessage.messageDirection,
// time: event.updatedConversationList[0].latestMessage.sentTime,
// msg: event.updatedConversationList[0].latestMessage.content.content,
// avatar: uni.getStorageSync('user_info').avatar
// });
// }
// },
// status: function(event) {
// let status = event.status;
// console.log('status num:', status);
// }
// });
/**
* 3.連接融云
* 1) 需要先調(diào)用服務(wù)端接口,獲取Token 然后進(jìn)行連接
*/
//進(jìn)行連接
this.$Im
.connect({
token: uni.getStorageSync('rong_token')
})
.then(user => {
console.log('success id: ', user.id);
})
.catch(error => {
console.log('error: ', error.code, error.msg);
});
},
聊天室代碼.js文件
export default {
name: 'index',
data() {
return {
chat: [],
sentText: '',
doctorInfo: '',
height: '0rpx',
scrollTop: 0,
count: 7,
uuid: '',
avatar: '',
list: [],
style: {
pageHeight: 0,
contentViewHeight: 0,
footViewHeight: 90,
mitemHeight: 0
},
};
},
onLoad(options) {
this.uuid = options.uuid
this.avatar = options.avatar
this.rongyunInit();
this.getlist(new Date())
const res = uni.getSystemInfoSync(); //獲取手機(jī)可使用窗口高度 api為獲取系統(tǒng)信息同步接口
this.style.pageHeight = res.windowHeight;
this.style.contentViewHeight = res.windowHeight - uni.getSystemInfoSync().screenWidth / 750 * (100); //像素 因為給出的是像素高度 然后我們用的是upx 所以換算一下
},
onShow() {
this.chat = []
this.clear()
},
methods: {
read(uuid, time) {
let conversation = this.$Im.Conversation.get({
targetId: this.uuid,
type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
});
let messageUId = uuid; // 消息唯一 Id, message 中的 messageUid
let lastMessageSendTime = time; // 最后一條消息的發(fā)送時間
let type = '1'; // 備用挚躯,默認(rèn)賦值 1 即可
// 以上 3 個屬性在會話的最后一條消息中可以獲得
conversation.send({
messageType: 'RC:ReadNtf',
content: {
messageUId: messageUId,
lastMessageSendTime: lastMessageSendTime,
type: type
}
}).then((message) => {
console.log('發(fā)送已讀通知消息成功', message);
});
},
scrolltoupper() {
this.$u.throttle(this.getlist(this.chat[0].time, 1), 500)
},
// 清空未讀數(shù)
clear() {
this.$Im.Conversation.getTotalUnreadCount().then(function(totalUnreadCount) {
console.log('獲取未讀總數(shù)成功', totalUnreadCount);
});
let conversation = this.$Im.Conversation.get({
targetId: this.uuid,
type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
});
conversation.read().then(()=> {
console.log('清除未讀數(shù)成功'); // im.watch conversation 將被觸發(fā)
});
},
scrollToBottom() {
let that = this;
let query = uni.createSelectorQuery();
query.selectAll('.m-item').boundingClientRect();
query.select('#scrollview').boundingClientRect();
query.exec((res) => {
console.log(res)
that.style.mitemHeight = 0;
res[0].forEach((rect) => that.style.mitemHeight = that.style.mitemHeight + rect.height + 40) //獲取所有內(nèi)部子元素的高度
// 因為vue的虛擬DOM 每次生成的新消息都是之前的强衡,所以采用異步setTimeout 主要就是添加了這定時器
setTimeout(() => {
if (that.style.mitemHeight > (that.style.contentViewHeight - 100)) { //判斷子元素高度是否大于顯示高度
console.log(3333)
that.scrollTop = that.style.mitemHeight - that.style.contentViewHeight //用子元素的高度減去顯示的高度就獲益獲得序言滾動的高度
}
}, 100)
})
},
// #ifdef APP-PLUS
hgit() {
this.height = '50rpx'
},
// #endif
// #ifdef H5
hgit() {
this.height = '500rpx'
},
// #endif
blur() {
this.height = '0rpx'
},
rongyunInit() {
//初始化融云
let _that = this;
//設(shè)置監(jiān)聽
let conversationList = []; //當(dāng)前存在的會話列表
_that.$Im.watch({
//對會話列表進(jìn)行監(jiān)聽
conversation: (event) => {
let updatedConversationList = event.updatedConversationList; //更新的會話列表
console.log('upload用戶端:', updatedConversationList);
let sendOut = {
content: event.updatedConversationList[0].latestMessage.content.content,
sentTime: event.updatedConversationList[0].latestMessage.sentTime
}
uni.setStorageSync('sendOut', sendOut)
if (event.updatedConversationList[0].latestMessage.messageDirection == 2) {
console.log('執(zhí)行了')
this.chat.push({
type: event.updatedConversationList[0].latestMessage.messageDirection,
time: event.updatedConversationList[0].latestMessage.sentTime,
msg: event.updatedConversationList[0].latestMessage.content.content,
avatar: uni.getStorageSync('user_info').avatar
})
}
},
status: function(event) {
let status = event.status;
console.log('status num:', status);
}
});
/**
* 3.連接融云
* 1) 需要先調(diào)用服務(wù)端接口,獲取Token 然后進(jìn)行連接
*/
//進(jìn)行連接
// this.$Im
// .connect({
// token: uni.getStorageSync('rong_token')
// })
// .then(user => {
// console.log('success id: ', user.id);
// })
// .catch(error => {
// console.log('error: ', error.code, error.msg);
// });
},
// 獲取歷史信息
getlist(time, status) {
console.log(time, status)
let conversation = this.$Im.Conversation.get({
targetId: this.uuid,
type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
});
let option = {
timestrap: +time,
count: this.count
};
conversation.getMessages(option).then((result) => {
this.list = result.list; // 歷史消息列表
let hasMore = result.hasMore; // 是否還有歷史消息可以獲取
console.log('獲取歷史消息成功', this.list, hasMore);
// this.read(this.list.length.messageUId, this.list.length.sentTime)
this.read(this.list[this.list.length-1].messageUId, this.list[this.list.length-1].sentTime)
// data == 1下拉加載
if (status == 1) {
let a = []
this.list.forEach(item => {
if (item.messageDirection == 1) {
a.push({
type: item.messageDirection,
time: item.sentTime,
msg: item.content.content,
avatar: uni.getStorageSync('user_info').avatar
})
} else {
a.push({
type: item.messageDirection,
time: item.sentTime,
msg: item.content.content,
avatar: this.avatar
})
}
})
console.log(2342342,a)
this.chat.unshift(...a)
console.log(this.chat)
}else{
this.list.forEach(item => {
if (item.messageDirection == 1) {
this.chat.push({
type: item.messageDirection,
time: item.sentTime,
msg: item.content.content,
avatar: uni.getStorageSync('user_info').avatar
})
} else {
this.chat.push({
type: item.messageDirection,
time: item.sentTime,
msg: item.content.content,
avatar: this.avatar
})
}
})
}
console.log(this.chat)
});
},
//融云發(fā)送消息方法
sendMessage(type, content) {
//4.連接融云成功后進(jìn)行發(fā)送消息
this.conversation = this.$Im.Conversation.get({
targetId: this.uuid,
type: this.$RongIMib.CONVERSATION_TYPE.PRIVATE
});
this.conversation.send({
messageType: this.$RongIMib.MESSAGE_TYPE[type],
content
}).then((msg) => {
this.scrollToBottom(); //創(chuàng)建后調(diào)用回到底部方法
console.log('發(fā)送消息成功', msg);
this.chat.push({
type: msg.messageDirection,
time: msg.sentTime,
msg: msg.content.content,
avatar: uni.getStorageSync('user_info').avatar
})
this.sentText = []
}).catch(err => {
console.log('消息發(fā)送失敗', err)
})
},
}
};
.vue文件
<template>
<view class="mh100p pd20 pb100" :style="{height: 100+'%'}">
<share title="即時通訊" />
<scroll-view id="scrollview" @scrolltoupper='scrolltoupper' class="chat-window pb100" scroll-y="true" :style="{ height: style.contentViewHeight + 'px' }" :scroll-with-animation="true" :scroll-top="scrollTop">
<view class="my20 m-item" v-for="(item, index) in chat" :key="index">
<view class="cl999 ftr26 mb20 u-text-center">{{ item.time | date('yyyy.mm.dd hh:MM:ss') }}</view>
<view class="yc" :class="item.type == 1 ? 'rever' : ''">
<u-avatar mode="square" :src="item.avatar"></u-avatar>
<view class="chat-box">{{ item.msg }}</view>
</view>
</view>
</scroll-view>
<view class="fix-wrap bgfff px30 py20 pb50" :style="{ bottom: height }">
<u-search
placeholder="請輸入發(fā)送內(nèi)容"
search-icon="edit-pen"
action-text="發(fā)送"
v-model="sentText"
@focus="hgit"
@blur="blur"
@custom="sendMessage('TEXT', { content: sentText })"
@search="sendMessage('TEXT', { content: sentText })"
></u-search>
</view>
</view>
</template>
<script>
import index from './index.js';
export default index;
</script>
<style lang="scss" scope>
@import './index.scss';
</style>
.css文件(用的ui庫是uview)
.chat-box {
padding: 20upx;
margin: 0 16upx;
background-color: #ffffff;
border-radius: 12upx;
}
.rever {
flex-direction: row-reverse;
.chat-box {
background-color: #f8e271;
}
}
.fix-wrap {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100upx;
}
/deep/ .u-input__input {
background-color: #f4f4f4;
border-radius: 20upx;
padding: 0 20upx;
}
即時通訊接起來還是挺麻煩的码荔,走一遍之后就還好漩勤,該有的api都有所提供,因為我是直接拿的項目里的缩搅,可能并不適用于你們