n How to use State Management Without Vuex in Vue.js | CodimTh

Please Disable Your Browser Adblock Extension for our site and Refresh This Page!

our ads are user friendly, we do not serve popup ads. We serve responsible ads!

Refresh Page
Skip to main content
On . By CodimTh
Category:

Simple state management can be performed by creating a store pattern that involves sharing a data store between components. The store can manage the state of our application as well as the methods that are responsible in changing the state.

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

We'll create a basic Javascript object:

const store = {};

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.

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.

 

Example 2:

For example, we can have a simple store like the following:

export const store = {
  state: {
    numbers: [1, 2, 3]
  },
  addNumber(newNumber) {
    this.state.numbers.push(newNumber);
  }
};

The store contains a numbers array within its state, and an addNumber method that accepts a payload and directly updates the state.numbers value.

We can have one component that’s responsible in displaying the numbers array from the store that we’ll call NumberDisplay:

<template>
  <div>
    <h2>{{ storeState.numbers }}</h2>
  </div>
</template>

<script>
import { store } from "../store.js";
export default {
  name: "NumberDisplay",
  data() {
    return {
      storeState: store.state
    };
  }
};
</script>

We can now have another component, called NumberSubmit, that will allow the user to add a new number to our data array:

<template>
  <div>
    <input v-model="numberInput" type="number" />
    <button @click="addNumber(numberInput)">
     Add new number
    </button>
  </div>
</template>

<script>
import { store } from "../store.js";
export default {
  name: "NumberSubmit",
  data() {
    return {
      numberInput: 0
    };
  },
  methods: {
    addNumber(numberInput) {
      store.addNumber(Number(numberInput));
    }
  }
};
</script>

 

The NumberSubmit component has an addNumber() method that calls the store.addNumber() mutation and passes the expected payload.

The store method receives the payload and directly mutates the store.numbers array. Thanks to Vue’s reactivity, whenever the numbers array in store state gets changed, the relevant DOM that depends on this value (<template> of NumberDisplayautomatically updates.

When we say components interact with one another here, we’re using the term ‘interact’ loosely. The components aren’t going to do anything to each other but instead invoke changes to one another through the store.

 

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook