State Management Without Vuex

What if you wanted to manage state, but you didn't want to use Vuex?

Don't get me wrong, Vuex is a great tool.

But it's not ideal for every use case.

Losing weight

I used to have this huge, heavy bible filled with all sorts of extra maps and details on things.

But it was really annoying to lug around.

So I got a new, lightweight one, which was accidentally printed upside down. I read this new one a lot more than I used to read my old one, because it's better suited for the task.

Sometimes it's good to shed a few pounds and switch to a lighter weight and easier method of doing things.

Vuex provides us with a great standard way of doing data management in Vue applications, but sometimes all of the required boilerplate can be tedious in a simple application.

Let me show you a simpler way.

It's waaaay easier than you think it is.

Data store pattern

One of the main benefits of Vuex is that it provides us with a data store.

It gives us a single location where all of our data sits.

Any component in the application can access it and update it, because it's globally accessible to the whole app.

Here's something you may not have realized:

We can build a very simple data store using only the core Vue framework.

This lightweight data store will also be a global, single location for us to put all of the application state into. And yes, we will make sure it's properly reactive too.

Storing data

Step one is to create a place where we can put all of our data.

We'll create a basic Javascript object:

const store = {};

That's it!

Just kidding.

If this tutorial ended here it would be pretty lame, so let's keep going.

We can store our data in a single place, but we still have some issues:

  1. We need to share this between all of our components
  2. We want this to be reactive

Sharing between components

We'll put this object into a file called store.js.

To share it with other components, we'll first have to export it from this file:

// store.js
export default {
movies: [],
};

Then for any component that needs to use the data store we can import it:

import store from './store.js';
export default {
name: 'CoolestComponent',
};

But using it is pretty tricky with Vue.

Right now it's not reactive, so it's impossible for us to know when something has been updated.

Currently this data store is only good for providing data on initialization.

In this example, if store.movies is updated after the component is created, nothing will happen:

import store from './store.js';
export default {
name: 'MovieList',
data() {
return {
movies: store.movies,
};
},
};

Making it reactive

Luckily Vue makes this part super easy for us with the Vue.observable function.

It takes in any object, and returns a copy of it that's reactive.

We'll use this on our data store to make it reactive:

// store.js
import Vue from 'vue';
export default Vue.observable({
movies: [],
});

That's the final step!

Now let's look at how we'll actually use this in a component.

Using our shiny data store

This is where we left off with our example:

import store from './store.js';
export default {
name: 'MovieList',
data() {
return {
movies: store.movies,
};
},
};

...but this component needs nothing added to it. It's already pulling the list of movies from the store, so it's doing everything it needs to.

Because the store is now reactive, whenever that value is updated it will update automatically and render the new list of movies.

What we need next is a way to load these movies in!

We'll create another component that does that:

// load-movies.vue
import store from './store.js';
import MoviesAPI from './moviesAPI.js';
export default {
name: 'LoadMovies',
methods: {
async loadMovies() {
// Add movies to our fancy data store
store.movies = await MoviesAPI.getMovies();
},
},
};

When the loadMovies method is called on this other component, it will fetch all of the movies and add them to our data store.