vue聊天功能之滚动条自动定位到底部

一、问题描述

首次进入聊天窗口,数据加载之后先显示最早消息,后显示最新消息,也就是数据加载完之后,延迟了一个时间滚动条才自动定位到最底部。

二、解决方案

  如果数据在刚好加载完的时候滚动条就定位到了最底部就好了,就不会在进入聊天窗口之后还看到滚动条在往下滚动,出现的问题就是因为获取数据和设置滚动条位置的代码不是同步的不是按顺序执行的,后者加了定时器。

  像微信聊天窗口一样,一进入到聊天窗口就看到滚动条是在聊天窗口的最底部。

  聊天窗口是一个组件,调起的不同的用户的聊天窗口都是这一个聊天窗口组件。

  聊天窗关键代码:

created() {
    bus.$on('getMessageData', (user)=> {
      this.userObj = JSON.parse(JSON.stringify(user))
      if(user && !user.id) {
        console.error("有问题userObj.id为:", user.id)
      }
      this.messageList = []
      this.$nextTick(()=> {
        setTimeout(() => {
          this.scrollContainer = document.querySelector('.chat-window-content')
          this.getUserToAssistantInfo()
          .then(() => {
            return this.getUserInfoList(user)
          })
          this.refresh(user)
        }, 100);
      })
    })
  }
async getUserInfoList(user) {
      return apis.getWxMessageData({user_id: user.id}).then(({data:{index, messages}}) => {
        this.index = index || ''
        this.messageList = messages || []
        this.$nextTick(() => {
            let el = this.scrollContainer
            el.scrollTop = el.scrollHeight-el.clientHeight
            // console.log(el, el.scrollTop, el.scrollHeight, el.clientHeight)
        })
      })
}

注意3个关键点:

 1、确保总是能拿到滚动区域的外层元素,用来定位滚动条的位置,也就是一定要在dom渲染能拿到dom元素再读取元素。

 2、在能拿到这个元素的情况下,去获取聊天内容。

 3、确保在获取到数据并渲染之后立即设置滚动条到最底部。

因为vue中dom数据的更新是异步的,vue中当观察到数据变化时,会开启一个队列,也就是最终数据的刷新会在下一个事件循环Tick中去执行。所以在获取到聊天内容之后,要立即更新滚动条的位置,必须放在nextTick中去执行设置滚动条位置的代码。

类似问题参考:

   vue踩坑日记之$nextTick:

  https://www.jianshu.com/p/d6cbcb0904c8?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

   简单理解vue中的nextTick:

   https://juejin.im/post/5a6fdb846fb9a01cc0268618

原文地址:https://www.cnblogs.com/yy95/p/9872386.html