How to create a Toasts Component in Vue 3 with Vuex
Toasts in a web application come in all different types and styles. Some codebases call them alerts, others bubbles, maybe even broadcasts — the list goes on and on. But one thing remains the same: web applications need a standard and good-looking way to send updates to users.
Every application handles this differently. Some applications handle it entirely on the backend, some entirely on the frontend. Implementations would even differ on applications built with the same frontend framework, like Vue, React, or Angular.
This is one way of creating a toasts component in your Vue project, using the power of Vuex.
Before continuing, I’m assuming you have introductory experience to Vue, JavaScript, and command line tools — mainly to use Vue CLI, a command-line tool for creating and maintaining vue projects.
Step 1: Creating the Project
Now, let’s get started. With the Vue CLI installed, create a new Vue 3 project with:
vue create vue-toasts
It will ask you for a preset — make sure to choose Default (Vue 3)
to get the latest version of Vue that you’ll be using to create this project.
Next, you’re going to install Vuex, Vue’s state management library. State management libraries in JavaScript frameworks are a way to access certain properties or functions anywhere in your app without the need to pass them down from component to component.
To install Vuex, run the command below in your project. It will overwrite src/main.js
to use Vuex, and create an empty Vuex store with state, mutations, actions, and modules. For this short project, you’ll only be using state and mutations, and we’ll cover each throughout this project.
vue add vuex
If you’re familiar with Git, now would be a good time to pause and commit what you have so far.
Step 2: Creating and testing the Vuex store
Next, we’re going to be setting up our Vuex store. First, we need to declare a state
object, which all Vuex stores use by default. Inside of this state object, we’re going to be adding an empty array of toasts: []
.
The toasts: []
will be the literal representation of toasts that we show to users in the application. Any component will be able to hook in to the current toasts available by using the function this.$store.state.toasts
.
After adding an initial state, we’ll add two mutations so that we can add and remove a toast from the toasts: []
array in the store. Any component in the application will be able to access these mutations by using the function this.$store.commit('mutation-name', argument)
.
Here’s what /src/store/index.js
should look like:
Now that the store is setup, we can get a basic example working on a component that Vue already created when the project was created through the Vue CLI: HelloWorld.vue
. Inside of this component, add the created()
lifecycle hook, and some new code to test the toasts store:
Accessing your Vuex stores inside of components is as easy as writing this.$store
. this.$store
gives you direct access to stores’ mutations, actions, state, and much more.
Let’s go through the code we just created. First, we create a couple of sanity checks: we console.log
the length of this.$store.state.toasts
before, and after we add a new toast.
In order to add a new toast, we use the mutation this.store.commit('add-toast')
, and we pass in an object: a new toast with a style, title, and message. We’ll explain and use all 3 of those properties soon.
If you go back and check your console, you should see the new toast there:
Now that you have a store setup for showing toasts, and a way to add them, you need a way to show the toasts on the page!
Step 3: Creating the toast components and showing a toast
First, let’s create an individual Toast component. Defining each toast as it’s own component will allow us to in the future automatically dismiss each toast after a certain amount of time.
Inside of /components
, create a new file named Toast.vue
. Each toast component will accept a prop, Toast
, which will be an object:
Second, you need to create a wrapper component that’s going to house all of these toasts.
Create another file inside of /components
named Toasts.vue
. Toasts
will have a computed property, toasts()
, that returns all toasts currently in the store. For every toast in the store, it will show the Toast
component on the page with that toast:
Last, to get the toasts to show up on the page, you need to import and display the Toasts
component inside of App.vue
. Placing the Toasts
component in App.vue
will allow toasts to show up on every single page in the application. Your final App.vue
should look like this:
After refreshing localhost:8080, the new toast should be there. You’re nearly to the finish line!
Step 4: Add styling to make them look like Toasts
Now you have a toast store and toasts showing up on the page. But they don’t really look like toasts yet. Proper toasts typically look like bubbles on the page: they’re to the side, nice to look at, and don’t interfere with the rest of the application. Let’s check all those boxes. To do this, we’ll need to:
- Add some colors (for success, info and error toasts)
- Add a dismissal functionality
- Push them to the side so they don’t interfere with the application
Open up your Toast.vue
component, and we’re going to add some CSS to it under <style>
:
Now with the CSS added to make them look like actual toasts, we need to:
- Add
:class
to dynamically match up the toast type with the proper colors set in CSS - Add a function in to call Vuex and remove the toast from
toasts: []
with a mutation, dismissing the toast - Add a button and click handler, as well as an automatic hook in
created()
to call this new function, allowing the user to dismiss the toast, and the toast to be dismissed automatically after a certain period of time
Back in your Toast.vue
component, we’re going to add all of this. This is what your finished component should look like:
Now if if you refresh localhost:8080, you should see a properly styled toast that you can dismiss, and will dismiss itself after 5 seconds:
Step 5: Finishing up and final tests
There’s only a couple more things needed to finish up:
- Add CSS to the
Toasts
wrapper component so that toasts don’t interfere with the rest of the application - Add additional toast types to the
created()
hook insideHelloWorld.vue
to see the different styles of toasts.
Open up Toasts.vue
, and add some additional CSS:
Lastly, open up HelloWorld.vue
and in the created()
hook, create two new additional toasts to test the error and info types:
Now if you refresh localhost:8080 one last time, you should see all 3 toasts - styled and properly placed on the page. You’re finished! Now whenever you make API calls, change a page, or complete an action in your application, you can give some great looking feedback to your users.
If you wanted to check out the full code for this short guide, it’s available on my personal Github here.