To add a scrolling effect that looks like the scrolling in a chat app in a Vue app, we can use the vue-chat-scroll library.
In this article, we’ll look at how to use the vue-chat-scroll library to add the chat scrolling effect.
Installation
We can install the library by running:
npm i vue-chat-scroll
We can also add the library with a script tag:
<script src="https://cdn.jsdelivr.net/npm/vue-chat-scroll/dist/vue-chat-scroll.min.js"></script>
Add the Chat Scroll Effect
We can add the chat scroll effect with the v-chat-scroll directive. To do that, we write:
<template>
<div id="app">
<ul class="messages" v-chat-scroll>
<li class="message" v-for="(n, i) in messages" :key="i">{{ n }}</li>
</ul>
<form @submit.prevent="addMessage">
<input v-model="message">
<input type="submit">
</form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: "",
messages: [
"Lorem",
"ipsum",
"dolor",
"sit",
"amet,",
"consectetur",
"adipiscing",
"elit.",
"Praesent",
"facilisis",
"justo"
]
};
},
methods: {
addMessage() {
this.messages.push(this.message);
this.message = "";
}
}
};
</script>
Now when we type something into the box and submit it, the v-chat-scroll directive will scroll to the bottom of the list.
We have a form that we submit add to the this.messages array.
Prevent Scroll Down When User has Scrolled Up and Smooth Scrolling
We can prevent the scroll down effect when the user scrolled up by setting the always property to false .
And we can add smooth scrolling with the smooth property set to true :
<template>
<div id="app">
<ul class="messages" v-chat-scroll="{always: false, smooth: true}">
<li class="message" v-for="(n, i) in messages" :key="i">{{ n }}</li>
</ul>
<form [@submit](http://twitter.com/submit "Twitter profile for @submit").prevent="addMessage">
<input v-model="message">
<input type="submit">
</form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: "",
messages: [
"Lorem",
"ipsum",
"dolor",
"sit",
"amet,",
"consectetur",
"adipiscing",
"elit.",
"Praesent",
"facilisis",
"justo"
]
};
},
methods: {
addMessage() {
this.messages.push(this.message);
this.message = "";
}
}
};
</script>
We can only add smooth scrolling for updates but not on first load with the notSmoothOnInit property:
<template>
<div id="app">
<ul class="messages" v-chat-scroll="{smooth: true, notSmoothOnInit: true}">
<li class="message" v-for="(n, i) in messages" :key="i">{{ n }}</li>
</ul>
<form [@submit](http://twitter.com/submit "Twitter profile for @submit").prevent="addMessage">
<input v-model="message">
<input type="submit">
</form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: "",
messages: [
"Lorem",
"ipsum",
"dolor",
"sit",
"amet,",
"consectetur",
"adipiscing",
"elit.",
"Praesent",
"facilisis",
"justo"
]
};
},
methods: {
addMessage() {
this.messages.push(this.message);
this.message = "";
}
}
};
</script>
We can also add the scrollonremoved property to ensure the scroll happens after the element loading indicator is removed:
<template>
<div id="app">
<ul class="messages" v-chat-scroll="{always: false, smooth: true, scrollonremoved:true}">
<li class="message" v-for="(n, i) in messages" :key="i">{{ n }}</li>
<li v-if="loading">...</li>
</ul>
<form [@submit](http://twitter.com/submit "Twitter profile for @submit").prevent="addMessage">
<input v-model="message">
<input type="submit">
</form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: "",
messages: [
"Lorem",
"ipsum",
"dolor",
"sit",
"amet,",
"consectetur",
"adipiscing",
"elit.",
"Praesent",
"facilisis",
"justo"
],
loading: false
};
},
methods: {
addMessage() {
this.loading = true;
setTimeout(() => {
this.messages.push(this.message);
this.message = "";
this.loading = false;
}, 1000);
}
}
};
</script>
We set this.loading to true when we submit the message and set it to false when it’s added.
Having the scrollonremoved property ensures that when the loading indicator is gone that the scrolling will happen.
Conclusion
The vue-chat-scroll library lets us scroll to the bottom of a list of text easily within a Vue app.