主要就是这行代码:
this.$nextTick(() => {
let ele = document.getElementById("scoll");
ele.scrollTop = ele.scrollHeight; //自动定位到底部
})
vue.$nextTick:
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,
完整示例:
<template>
<div style="width: 100%; height: 100%;">
<el-row style="position: relative; height: 100%; width: 100%">
<el-col :span="24" style="height: 600px; overflow-y: auto; border-bottom: 1px solid #cccccc; background-color: #F6F6F6" id="scoll" >
<div style="width: 100%;">
<div v-for="item in daMessage">
<div style="margin-bottom: 10px; box-sizing: border-box; width: 100%;float: left" v-if="!item.from">
<div
style="background-color: #1E9FFF; padding: 10px 15px; max-width: 150px; font-size: 13px; overflow: hidden; white-space: normal; word-break: break-all; color: #ffffff; border-radius: 3px; float: left">
{{ item.message }}
</div>
</div>
<div style=" float: right; margin-bottom: 10px; box-sizing: border-box; width: 100%" v-else>
<div
style="background-color: #42b983; padding: 10px 15px; max-width: 150px; font-size: 13px; overflow: hidden; white-space: normal; word-break: break-all; color: #ffffff; border-radius: 3px;float: right">
{{ item.message }}
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="24" style="position: fixed; bottom: 1px;width: 95%">
<el-row justify="center" align="middle">
<el-col :span="20">
<el-input type="textarea" v-model="message" @keydown.enter.native="keyDown" :rows="6" resize="none" placeholder="Enter发送,CTRL+Enter换行"></el-input>
</el-col>
<el-col :span="4" style="background-color: #1E9FFF;" @click="send">
<el-button type="primary">发送</el-button>
</el-col>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
message: "",
daMessage: [],
count: 0,
socket: null
}
},
methods: {
send() {
if (this.message === "") return this.$layer.msg("请输入消息内容")
this.socket.send(JSON.stringify({
type: "data",
from: 1,
to: 2,
message: this.message
}))
this.daMessage.push({
message: this.message,
from: true
})
this.message = "";
this.$nextTick(() => {
let ele = document.getElementById("scoll");
ele.scrollTop = ele.scrollHeight; //自动定位到底部
})
},
onOpen() {
this.socket.send(JSON.stringify({
type: "bind",
uid: 1
}))
},
onMessage(data) {
let audio = new Audio();
audio.src = require("../assets/audio/9586.mp3");
audio.play();
let da = JSON.parse(data.data);
this.daMessage.push({
message: da.message,
from: false
})
this.$nextTick( () => {
let ele = document.getElementById("scoll")
ele.scrollTop = ele.scrollHeight; //自动定位到底部
})
},
onerror() {
this.count++;
setTimeout(() => {
if(this.count > 10) {
return this.$layer.msg("客服系统连接失败,请联系管理员解决!", {icon:5})
}
this.$message.error(`客服系统连接失败,正在第${this.count}次重连!`);
this.socket = new WebSocket(this.$Api.socketUrl);
this.socket.onopen = this.onopen;
this.socket.onmessage = this.onmessage;
this.socket.onerror = this.onerror;
},2000)
},
keyDown(e) {
if(e.ctrlKey && e.keyCode === 13) {
this.message += "\n";
}else if(e.keyCode === 13) {
this.send();
e.preventDefault();
}else {
e.preventDefault();
}
}
},
mounted() {
},
created() {
this.socket = new WebSocket(this.$Api.socketUrl);
this.socket.onopen = this.onOpen
this.socket.onmessage = this.onMessage;
this.socket.onclose = this.onclose;
this.socket.onerror = this.onerror;
}
}
</script>
<style scoped>
/*自定义滚动条*/
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar{
width: 7px;
height: 7px;
background-color: #F5F5F5;
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
background-color: #F5F5F5;
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb{
border-radius: 10px;
box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
background-color: #c8c8c8;
}
</style>
到此这篇关于VUE聊天页面自动滚动到底部就介绍到这了。人生如同没有回头路的拾荒,想走得远,享受到更多精彩,你不能背得太重,必须经常清理背篓,该扔该留不要犹豫。更多相关VUE聊天页面自动滚动到底部内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!