1.设置最外层div可滚动,并隐藏滚动条
<div class="home" ref="main">
.home {
width: 100%;
height: calc(100% - 60px);
overflow: hidden;
overflow-y: auto;
padding-bottom: 50px;
background: #eaecee;
// 隐藏滚动条
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+, edge */
&::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
}
2.聊天信息的容器,也绑定一个ref
<div class="msg" ref="content">
.msg {
margin-top: 46px;
width: 100%;
padding: 0 10px;
box-sizing: border-box;
}
3.因为第一次进入聊天页面(和发送消息),聊天信息必须在底部 ,可以在created里面调用这个方法
this.$nextTick(() => {
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
});
4.接收消息,最后一条信息也要出现在底部
watch: {
recvList: function (val) {
console.log(val, 11);
this.chatMessages.push({
infos: val.message,
files: val.files,
send_user: val.send_user,
});
this.$nextTick(() => {
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
});
},
},
----》根据存储的角色id和接收信息人的id来判断显示在左边还是右边
<!-- 聊天信息 -->
<div class="msg" ref="content">
<div
v-for="(item, index) in chatMessages"
:key="index"
:class="[item.send_user.id == userId ? 'msg-r' : 'msg-l']"
>
<div v-if="item.send_user.id === userId" class="msg-right">
<span class="chat-txt">{{ item.infos }}</span>
<div>
<img src="../../assets/logo.png" alt="" />
</div>
</div>
<div v-else class="msg-left">
<div>
<img
style="width: 36px; height: 36px"
src="../../assets/logo.png"
alt=""
/>
</div>
<span class="chat-txt">{{ item.infos }}</span>
</div>
</div>
</div>
3.写的有点乱了 直接贴全部
<template>
<div class="home" ref="main">
<div class="goods_info">
<van-nav-bar
class="nav-bar"
:fixed="true"
:title="recv_user.name"
left-arrow
@click-left="backback"
/>
</div>
<!-- 聊天信息 -->
<div class="msg" ref="content">
<div
v-for="(item, index) in chatMessages"
:key="index"
:class="[item.send_user.id == userId ? 'msg-r' : 'msg-l']"
>
<div v-if="item.send_user.id === userId" class="msg-right">
<span class="chat-txt">{{ item.infos }}</span>
<div>
<img src="../../assets/logo.png" alt="" />
</div>
</div>
<div v-else class="msg-left">
<div>
<img
style="width: 36px; height: 36px"
src="../../assets/logo.png"
alt=""
/>
</div>
<span class="chat-txt">{{ item.infos }}</span>
</div>
</div>
</div>
<!-- <div
:class="[
item.recv_user.name != Activename ? 'msg-ritime' : 'msg-time',
]"
>
{{ TimeDate(item.update_time) || TimeDate(new Date()) }}
</div> -->
<!-- 上面为聊天信息 -->
<!-- 下面是操作键盘 -->
<!-- 未使用popup -->
<div class="bom">
<div>
<!-- 左 -->
<img
v-if="changeAudio === false"
src="../../assets/image/audio.png"
alt=""
@click="clickaudio()"
/>
<img
v-else
@click="clickaudio()"
src="../../assets/image/jianpan.png"
alt=""
/>
</div>
<!-- 中 -->
<div class="changeAudio">
<van-cell-group v-if="changeAudio">
<van-field
class="input-msg"
value="按住说话"
input-align="center"
readonly
/>
</van-cell-group>
<van-cell-group v-else>
<van-field
class="input-msg"
@focus="changeInput"
v-model="msgObj.message"
ref="input"
></van-field>
</van-cell-group>
</div>
<!-- 右 -->
<div>
<van-button
type="info"
class="send"
size="mini"
v-if="msgObj.message !== '' && changeAudio === false"
@click="send()"
>发送</van-button
>
<img
v-else
class="right-img"
src="../../assets/image/add.png"
alt=""
@click="popShow"
/>
</div>
</div>
<!-- popup -->
<van-popup
:class="[keyboard === true ? 'keyboard-show' : 'wechat-show']"
v-model="imgPop"
position="bottom"
>
<div class="bom-pop">
<div>
<img
v-if="changeAudio === false"
src="../../assets/image/audio.png"
alt=""
@click="clickaudio()"
/>
<img
v-else
@click="clickaudio()"
src="../../assets/image/jianpan.png"
alt=""
/>
</div>
<div class="changeAudio">
<van-cell-group v-if="changeAudio">
<van-field
value="按住说话"
class="input-msg"
input-align="center"
readonly
/>
</van-cell-group>
<van-cell-group v-else>
<van-field
@focus="changeInput"
class="input-msg"
v-model="msgObj.message"
/>
</van-cell-group>
</div>
<!-- 右 -->
<div>
<van-button
type="info"
class="send"
size="mini"
v-if="msgObj.message !== '' && changeAudio === false"
@click="send()"
>发送</van-button
>
<img
v-else
src="../../assets/image/remove.png"
alt=""
@click="popShow"
/>
</div>
</div>
<div v-if="keyboard === false">
<div style="margin-top: 60px"></div>
<div class="img-pop">
<div class="imgs">
<img src="../../assets/image/paizhao.png" alt="" />
<div>拍照</div>
</div>
<div class="imgs">
<img src="../../assets/image/wenjianjia.png" alt="" />
<div>文件</div>
</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
export default {
// 接收聊天记录
props: ["recv_user"],
watch: {
recvList: function (val) {
console.log(val, 11);
this.chatMessages.push({
infos: val.message,
files: val.files,
send_user: val.send_user,
});
this.$nextTick(() => {
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
});
},
},
data() {
return {
msgObj: {
message: "",
files: [],
recv_user: "",
},
imgPop: false,
value: "",
keyboard: false,
changeAudio: false,
Activename: "",
chatMessages: [],
};
},
computed: {
recvList() {
return this.$store.getters.recvList;
},
},
created() {
this.initMessage();
this.userId = JSON.parse(localStorage.getItem("id")).id;
this.Activename = JSON.parse(localStorage.getItem("id")).name;
this.msgObj.recv_user = this.recv_user.id;
},
methods: {
initMessage() {
this.$api.message_list(this.recv_user.id).then((res) => {
this.chatMessages = res.reverse();
this.$nextTick(() => {
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
});
});
},
backback() {
this.$emit("wechatClick");
},
// 点击调起发送文件
popShow() {
this.keyboard = false;
this.imgPop = !this.imgPop;
},
// 点击调起键盘
changeInput() {
this.keyboard = !this.keyboard;
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
},
// 点击切换为音频
clickaudio() {
this.imgPop = false;
this.changeAudio = !this.changeAudio;
// 音频切换为别的图标时 直接调用键盘
// if (this.changeAudio === true) {
// this.$refs.input.focus();
// console.log(1);
// }
},
send() {
this.chatMessages.push({
infos: this.msgObj.message,
files: [],
send_user: {
id: this.userId,
name: this.Activename,
},
});
this.$nextTick(() => {
this.$refs.main.scrollTop = this.$refs.content.scrollHeight;
});
this.$store.dispatch("WEBSOCKET_SEND", this.msgObj);
this.msgObj.message = "";
this.$refs.input.focus();
},
},
};
</script>
<style lang="scss" scoped>
.focusState {
position: absolute;
}
.home {
width: 100%;
height: calc(100% - 60px);
overflow: hidden;
overflow-y: auto;
padding-bottom: 50px;
background: #eaecee;
// 隐藏滚动条
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+, edge */
&::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
}
.nav-bar {
background: var(--themeColor);
}
::v-deep .van-nav-bar__text {
color: #fff !important;
}
.goods_info ::v-deep .van-nav-bar__title {
color: #fff !important;
font-weight: 500;
font-size: 18px;
}
::v-deep .van-nav-bar .van-icon {
color: #fff;
}
.msg {
margin-top: 46px;
width: 100%;
padding: 0 10px;
box-sizing: border-box;
.msg-r {
display: flex;
justify-content: flex-end;
.msg-right {
display: flex;
margin-top: 10px;
img {
width: 2rem;
height: 2rem;
}
.chat-txt {
padding: 10px;
font-size: 16px;
margin: 5px 10px 0 0;
color: #212121;
background: #fff;
border-radius: 5px;
}
}
.msg-time {
margin-left: 50px;
margin-top: 5px;
font-size: 12px;
color: #666;
}
.msg-ritime {
margin-top: 5px;
font-size: 12px;
color: #666;
}
}
.msg-l {
.msg-left {
margin-top: 10px;
display: flex;
img {
width: 2rem;
height: 2rem;
}
.chat-txt {
padding: 10px;
font-size: 16px;
margin: 5px 0 0 10px;
color: #212121;
background: #fff;
border-radius: 5px;
}
}
.msg-time {
margin-right: 50px;
margin-top: 5px;
font-size: 12px;
color: #666;
}
}
}
.bom-pop {
display: flex;
align-items: center;
position: fixed;
width: 100%;
height: 50px;
justify-content: space-around;
background: #f4f5f6;
img {
width: 28px;
height: 28px;
margin: 5px 10px 0 10px;
}
.audio {
height: 36px;
width: 100%;
display: flex;
background: #fff;
font-size: 15px;
font-weight: 600;
justify-content: center;
align-items: center;
}
.send {
width: 40px;
height: 28px;
color: #fff;
font-size: 12px;
display: flex;
margin: 0 10px;
border-radius: 4px;
align-items: center;
justify-content: center;
background: #2a78f4;
}
}
.img-pop {
display: flex;
margin-left: 35px;
font-size: 12px;
color: #666;
text-align: center;
.imgs {
margin-right: 35px;
img {
width: 50px;
height: 50px;
}
}
}
.bom {
display: flex;
align-items: center;
position: absolute;
bottom: 0;
width: 100%;
height: 50px;
background: #f4f5f6;
img {
width: 28px;
height: 28px;
margin: 5px 10px 0 10px;
}
.audio {
height: 36px;
padding: 0 70px;
display: flex;
background: #fff;
font-size: 15px;
font-weight: 600;
justify-content: center;
align-items: center;
}
.send {
width: 40px;
height: 28px;
color: #fff;
font-size: 12px;
display: flex;
margin: 0 10px;
border-radius: 4px;
align-items: center;
justify-content: center;
background: #2a78f4;
}
}
.wechat-show {
width: 100%;
height: 46%;
background: #f4f5f6;
}
.keyboard-show {
width: 100%;
height: 12%;
background: #f4f5f6;
}
.changeAudio {
display: flex;
justify-content: center;
width: calc(100% - 96px);
.van-cell-group {
height: 100%;
width: 100%;
}
}
.input-msg {
height: 95%;
width: 100%;
font-weight: 400;
line-height: 1;
}
</style>