Vue controls the position of the scroll bar after rendering the data


foreword

The demand scenarios are as follows:

The message sending is realized. If there are too many messages in the container, a scroll bar will appear. The latest message is at the bottom and cannot appear in the visible area in time. At this time, after rendering the list, position the scroll bar to the bottom bottom. Let's take a look at the final effect
insert image description here


Implementation ideas

  • After rendering the data, get the actual height of the message container through the refs object
  • Set the scroll bar to the bottom

Implementation process

sendMessage: function (event) {
    
    
  // 数据渲染
  this.senderMessageList.push(thisSenderMessageObj);
  // 改变滚动条位置
  this.messagesContainerTimer = setTimeout(()=>{
    
    
    this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight;
    console.log("当前滚动条位置:"+this.$refs.messagesContainer.scrollTop);
    console.log("当前可滚动区域容器的高度:"+this.$refs.messagesContainer.scrollHeight);
    // 清理定时器
    clearTimeout(this.messagesContainerTimer);
  },0);
}

Trample record

Set the position of the scroll bar directly

After the data rendering is completed, the real height of the element is obtained directly, and the position of the scroll bar is set. Reasonably, there seems to be nothing wrong with it. As a result, the height of the scroll bar is not rendered as expected.

Cause of the problem: After the data rendering is completed, Vue has not rendered the DOM element at this time, and the set scroll bar height is still the previous container height.

sendMessage: function (event) {
    
    
  // 数据渲染
  this.senderMessageList.push(thisSenderMessageObj);
  // 改变滚动条位置
  this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight;
  console.log("当前滚动条位置:"+this.$refs.messagesContainer.scrollTop);
  console.log("当前可滚动区域容器的高度:"+this.$refs.messagesContainer.scrollHeight);
}

insert image description here
The correct way to change: Use setTimeout() to change the DOM operation to asynchronous.

this.messagesContainerTimer = setTimeout(()=>{
    
    
  this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight;
  console.log("当前滚动条位置:"+this.$refs.messagesContainer.scrollTop);
  console.log("当前可滚动区域容器的高度:"+this.$refs.messagesContainer.scrollHeight);
  // 清理定时器
  clearTimeout(this.messagesContainerTimer);
},0);

Guess you like

Origin blog.csdn.net/weixin_48353638/article/details/129382195