问答

使用vue 在写 多人聊天区域 遇到的问题

作者:admin 2021-07-09 我要评论

问题描述 开始我模拟数据,每一秒一条消息 ,最新消息自动到底部,但是我想滚动滑轮,查看之前消息的时候,这个时候来新消息了,又到下面了 问题出现的环境背景...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

问题描述

开始我模拟数据,每一秒一条消息 ,最新消息自动到底部,但是我想滚动滑轮,查看之前消息的时候,这个时候来新消息了,又到下面了

问题出现的环境背景及自己尝试过哪些方法

没有思路

相关代码

这是我目前的写法

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

你期待的结果是什么?实际看到的错误信息又是什么?

我想要实现,在我没滚动的时候,最新消息 还是滚动底部,当我滚动滑轮时候,消息正常更新 但是 不滚动到底部 当我不滚动过5秒 消息这个时候 滚动底部,

###

添加滚轮事件,设置状态,在新消息来时判断该状态再决定是否滚动到底部

###

定义定时器 timer;
监听消息 list,有新消息时this.timer = setTimeout(fn,5000) 5s后执行置底,同时监听滚动条滚动事件,如果滚动的话clearTimeout(this.timer)取消置底操作;

不过正常像QQ聊天的话,通常你翻记录看消息时,然后5s不动滚动条也应该保持原来位置并在最底部提示有多少条新消息。(与底部距离定义一个区间,如果超过这个距离应该保持滚动条,如果小于这个距离置底)

###

判断一下,如果当前滚动条在最下面,就滚动,如果不在最下面,就不滚。

###

点击测试-codepen

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

<script>
export default {
  data() {
    return {
      list: [],
      isScrolling: false,
      setScrollStatus: undefined,
    };
  },
  created() {
    setInterval(() => {
      this.list.push("一条新消息");
    }, 1000);
  },
  mounted() {
    this.$refs.chat.onwheel = (e) => {
      clearTimeout(this.setScrollStatus);
      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;
        });
      },
    },
  },
};
</script>

<style scoped lang="less">
.chat-container {
  width: 360px;
  height: 500px;
  margin: auto;
  border: 1px solid red;
  overflow: auto;
  .message {
    margin: 20px 0;
  }
}
</style>
###

从逻辑上,这样判断更合理

最后一条消息 在可视范围内(即可见,部分可见也视为可见),自动下滚显示新消息
最后一条消息 不在可视范围内(即不可见),不自动滚动
###

我采用的逻辑是 定义一个阈值,如果超过了就不自动滚动,没超过就自动滚动

自动滚动的逻辑要写多个

  1. 接收到他人消息(走阈值逻辑)
  2. 自己发送消息(强制滚动)
  3. 查看历史消息(保持滚动条位置),这里可以缩短条数

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • elementUI表单Object.assign处理后无法

    elementUI表单Object.assign处理后无法

  • nacos作为配置中,有时可以加载到配置

    nacos作为配置中,有时可以加载到配置

  • font-spider压缩字体后,文件大小没有

    font-spider压缩字体后,文件大小没有

  • Vue SSR babel node_modules中的一个包

    Vue SSR babel node_modules中的一个包

腾讯云代理商
海外云服务器