- Part 1 - Getting Started
- Part 2 - Site Data and Vuex Store (You are here)
- Part 3 - Displaying Posts and Adding Some Style
Getting Site Data
When we finished off last time, we had a very (very, very) basic page that displayed only the titles and excerpts for the five most recent posts. I’m not out to revolutionize blogging or anything, but I think it might also be a good idea to display the name of the blog on the home page.
In order to do that, we need to get that data and then display that data.
Let’s add a method to get the data to our WordPress REST API library:
The base endpoint for the API returns basic site data along with a list of all endpoints for the API. We only need the site data, so we’ll discard the rest.
Now we need to display the data.
In our index page, we’ll update our
asyncData method to use our new
asyncData must return a promise that resolves to an object that will be merged with the component state, so we’ll use
Promise.all() to make each call to the API.
Promise.all() resolves to an array of the results for all promises, so we’ll call
reduce() to combine the results into one object.
We’ve added a
<header> to our template that displays the site name and tagline. Note that we use the built-in
<nuxt-link> component to create a link.
We’ll also update the
title in our HTML
head. This requires the
head() method which returns an object that updates the data in the head. In the
head() method, our
site_data object that we retrieved in the
asyncData() method is available as a property of
Setting up Vuex
This works great if we only have a single page, but even my neglected blog has more than one post. We don’t want to have to call out for site data every time we load a new page and it would be great if we didn’t have to clutter up our
asyncData() method with an extra call, too.
Vuex is a flux-like state management library for Vue. Vuex is built in to Nuxt and Nuxt has a couple of special hooks to make our life easier.
We can set up a Vuex store and load the site data into the store the first time we render a page. The data will be there for use for the remainder of the session. Later on, we can use our store to hold other things like post and navigation data.
Let’s set up our store.
All you need to create your Vuex store in Nuxt is an
index.js file in the store folder with a default export of a function that returns a
Vuex.Store. Our purposes are pretty simple, so we can get away with using a single store file, but you can also use a module pattern so long as your final store is exported from
There are three parts here in our initial store:
state— This is where we initialize our store. We can start with an empty site data object.
mutations— In Vuex, you make updates to state by calling the store’s commit method identifying a mutation to perform. Our
SITE_DATA_UPDATEmutation simply replaces the existing site data with the object passsed in as the payload on the commit. Note that we’re exporting our mutation names to make it easy to reference them throughout the app.
actions— In Vuex, mutations are synchronous. To perform asynchronous updates, we use actions.
nuxtServerInit()is a special action in Nuxt that is called when the Vuex store is first created. Our
nuxtServerInit()action fetches the site data from the WordPress REST API then commits the
SITE_DATA_UPDATEmutation passing the site data as the payload.
Now using our Vuex store, the site data that was part of component state in
index.vue is now stored in the Vuex store for use throughout our session. We won’t need to fetch it again every time we load a new page.
Adding the Header to Our Layout
Now that we’ve moved the site data from component state to our Vuex store, we need to update how we’ll display it. The purpose of adding the site data to our Vuex store was so that we don’t have to fetch the data for every page, so it would be nice if we also don’t have to add the header individually to every page in our site.
Let’s start by updating the title in the
head element for our index page.
We’ll undo our changes from above, remove the
<header> from our template, and go back to only calling out for post data from our
asyncData() method. Nuxt automatically injects the Vuex store into our components, so it is available from
this.$store. In our
head() function, we can now access the site name from the store instead of component state.
To display the header on every page, we’re going to use layouts. In Nuxt, layouts are the base components. The contents of the page components are displayed in a layout component. (By default, the aptly-named
default.vue component, though you can use different layouts throughout your app by specififying a different layout in your page component.)
The default layout component doesn’t do anything except display the contents of the page component using the
We’re going to create a header component that displays the site data that we’ve fetched into our Vuex store and then add that component to the
BlogHeader component takes the site data as props and uses the same header that we created in our initial version at the beginning of this post. We’ll still need to inject our data from the store. We’ll do that when we update the
We need to add a script section to import and use our new
BlogHeader component. In the
template, we could use the injected store to directly pass the site data as props to our
BlogHeaer component like this:
<blog-header :siteData="$store.state.site_data" />
To be a little cleaner, we’ll use the Vuex
mapState helper. The simple format for
mapState just takes an array of property names from the store and makes those available as props. So,
this.$store.state.site_data is now available in props as
site_data. We can just pass that into our
Boom! After all that work, we’re exactly where we were when we started. Awesome.
I kid, I kid. We may look exactly the same, but we’ve saved ourself a bunch of data calls and effort going forward.
As you can see, adding a Vuex store gives us a lot of power to let us reuse code and data and make our lives easier.
You can also check out the entire repo on GitHub at this point in project.
Next time, we’ll learn more about routing when we create pages for our posts and then we’ll have some fun adding a little style.