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.