我正在尝试使用Vue和Express制作聊天应用程序。
目前,我希望在发送新邮件时使带有邮件的容器自动滚动到底部。我尝试使用scrollToEnd
函数选择div容器并将其scrollHeight
分配给scrollTop
:
scrollToEnd: function () {
var messages = this.$el.querySelector('#messages')
messages.scrollTop = messages.scrollHeight
}
这会出现以下错误:
TypeError:无法读取null
的属性'scrollHeight'
出于某种原因,使用querySelector
总是返回null,当我在其他元素上测试时也是如此。
可以找到该组件的完整代码。
<template>
<div id="messages">
<ul>
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</div>
</template>
<script>
import MessageService from '@/services/MessageService'
export default {
name: 'messages',
data () {
return {
messages: []
}
},
mounted () {
this.getMessages()
this.$root.$on('newMessage', (msg) => {
this.message = msg
this.getMessages()
this.scrollToEnd()
})
},
methods: {
async getMessages () {
const response = await MessageService.fetchMessages()
this.messages = response.data.messages
},
scrollToEnd: function () {
var messages = this.$el.querySelector('#messages')
messages.scrollTop = messages.scrollHeight
}
}
}
</script>
答案 0 :(得分:1)
this.$el
Vue实例正在管理的根DOM元素。
this.$el
#messages
div,无需从DOM中获取。
然后,你可以简单地使用this.$el.lastElementChild.offsetTop
来获取最后一条消息并滚动到它的顶部,所以如果它很长,你就不会滚动到它的起点。
在这里,我简化了模板,使其直截了当。
<template>
<ul id="messages">
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</template>
<script>
export default {
name: 'messages',
data() {
return { messages: [] };
},
mounted() {
this.getMessages();
},
updated() {
// whenever data changes and the component re-renders, this is called.
this.$nextTick(() => this.scrollToEnd());
},
methods: {
async getMessages () {
// ...snip...
},
scrollToEnd: function () {
// scroll to the start of the last message
this.$el.scrollTop = this.$el.lastElementChild.offsetTop;
}
}
}
</script>
如果您真的想保留<div>
容器,可以使用ref
。
<template>
<div id="messages">
<ul ref="list">
<li v-for="msg in messages.slice().reverse()">{{ msg.message }}</li>
</ul>
</div>
</template>
然后在组件中,您可以使用this.$refs.list
来引用它。
ref
用于注册对元素或子元素的引用 零件。该参考将在父母下注册 组件的$refs
对象。如果在普通的DOM元素上使用,那么 参考将是那个元素;如果在儿童组件上使用, 引用将是组件实例。
虽然Vue示例通常使用本机DOM API来解决,但在此实例中使用ref
会更容易。