Sign in

Problems in using Vue to write multi person chat area

Nexsys edited in Thu, 26 Jan 2023

Problem description

At the beginning, I simulated the data, one message per second, and the latest message was automatically sent to the bottom. But I want to scroll the pulley to check the previous message. At this time, the new message came, and then it came to the bottom

The background of the problem and what methods have you tried

No idea

Related codes

This is how I write it now

 watch: {
    list() {
      this.$nextTick(() => {
        let msg = document.getElementById("chatContainer"); // 获取对象;
        msg.scrollTop = msg.scrollHeight; // 滚动高度

What are your expectations? What is the actual error message?

I want to realize that when I don't scroll, the latest message will still scroll to the bottom. When I scroll the pulley, the message will be updated normally but will not scroll to the bottom. When I don't scroll for 5 seconds, the message will scroll to the bottom,

6 Replies
commented on Thu, 26 Jan 2023

Add a scroll wheel event, set the status, judge the status when a new message comes, and then decide whether to scroll to the bottom

commented on Thu, 26 Jan 2023

Define timer; Listen to the message list, when there is a new message this.timer =After 5 seconds of setTimeout (FN, 5000), set the bottom and monitor the scrolling events of the scroll bar. If scrolling, cleartimeout will be executed( this.timer )Cancel the bottom setting operation;

But normally, like QQ chat, usually when you look at the message through the record, and then the 5S fixed scroll bar should also keep the original position and prompt how many new messages there are at the bottom( Define an interval from the bottom. If the distance exceeds, the scroll bar should be kept. If the distance is less than, the scroll bar should be set at the bottom.)

commented on Fri, 27 Jan 2023

If the current scroll bar is at the bottom, it will scroll. If it is not at the bottom, it will not scroll.

commented on Fri, 27 Jan 2023

Click test codepen

    <div class="chat-container" ref="chat">
      <div class="message" v-for="(chat, chatIndex) in list" :key="chatIndex">
        {{ chat }}

export default {
  data() {
    return {
      list: [],
      isScrolling: false,
      setScrollStatus: undefined,
  created() {
    setInterval(() => {
    }, 1000);
  mounted() {
    this.$refs.chat.onwheel = (e) => {
      this.isScrolling = true;
      this.setScrollStatus = setTimeout(() => {
        this.isScrolling = false;
      }, 5000);
  methods: {},
  watch: {
    list: {
      handler(newVal) {
        this.$nextTick(() => {
          if (this.isScrolling) return;
          this.$refs.chat.scrollTop = this.$refs.chat.scrollHeight;

<style scoped lang="less">
.chat-container {
  width: 360px;
  height: 500px;
  margin: auto;
  border: 1px solid red;
  overflow: auto;
  .message {
    margin: 20px 0;
commented on Fri, 27 Jan 2023

Logically, this is more reasonable

If the last message is visible (that is, visible or partially visible), it will scroll down automatically to display the new message. If the last message is not visible, it will not scroll automatically
commented on Fri, 27 Jan 2023

The logic I use is to define a threshold value. If it exceeds, it will not scroll automatically. If it doesn't exceed, it will scroll automatically

The logic of automatic scrolling needs to write multiple

  1. Receiving other people's message (threshold logic)
  2. Send your own message (force scrolling)
  3. View the history message (keep the scroll bar position), here you can shorten the number of messages