VUE聊天页面自动滚动到底部

雪花在空中嬉戏着、飞舞着,它净化了世间的一切尘埃,送走了严冬的寂寞,它自由地来,潇洒地去,多少著名的诗词都赞美过它: "忽如一夜春风来,千树万树梨花开 ",多么俏丽呀! "瑞雪兆丰年 ",它还是丰收的预言家呢!

主要就是这行代码:

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聊天页面自动滚动到底部内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!

您可能有感兴趣的文章
vue、nginx部署后刷新报404错误的解决方法

VUE CTRL+ENTER换行,ENTER发送消息

Vue 3自定义指令开发的相关总结

vue动态绑定图标的完整步骤

Vue新手指南之创建第一个vue-cli脚手架程序