Universal Vue.js application with Nuxt.js part#2 Vuex in Nuxt.js, Classic Mode and Modules Mode

in #utopian-io6 years ago (edited)

Screenshot_17.png

Repository

https://github.com/nuxt/nuxt.js

What Will I Learn?

  • Use Vuex in Nuxt.js
  • State, Mutations, Actions
  • How to write Classic mode and Modules mode

Requirements

  • Basic Javascript Es6
  • Basic Vuejs
  • Install Nuxt.js
  • Basic Vuex

Resources

Nuxt.js Website - https://nuxtjs.org/
Nuxt.js Github. - https://github.com/nuxt/nuxt.js
Vuex - https://github.com/vuejs/vuex

Difficulty

  • Intermediated

Tutorial content

This is a tutorial series about Nuxt.js. in the previous tutorial, we have learned the basics about Nuxt.js interfaced with the API. In this tutorial, we will learn much more deeply about Nuxt.js. We will learn how to use Vuex in Nuxt.js and how the interaction of data from Vuex can access in a page.

Why we should use Vuex ?

Vuex is a state management pattern and library for Vue.js applications. Vuex serves as a centralized store for all components. That means the data available on Vuex can be used in any component, by using Vuex data in our application to be neater and more centralized. but if the data you use is small you can use props and event emits to other components to communicate.

When should we use Vuex ?

Whenever you feel the data you need is too much and scattered and in my experience you have to use Vuex on the data continues to grow. If you look at my previous tutorial , we process the data on the same page.

Index.vue

<template>
  <section class="container">
    <div style="text-align: center;">
      <app-logo/>
      <h1 class="title">
        millenuxt
      </h1>
      <h2 class="subtitle">
        tutorial
      </h2>
    </div>
    <div class="list-group">
        <a href="#" class="list-group-item list-group-item-action active">
          List data from API
        </a>
        <a v-for="item in pokemons" :key="item.name" href="#" class="list-group-item list-group-item-action">{{item.name}}</a>
    </div>
  </section>
</template>

<script>
  import AppLogo from '~/components/AppLogo.vue'
  import axios from '~/plugins/axios'
  export default{
    components: {
      AppLogo
    },
    asyncData(){
        return axios.get('pokemon').then(res=>({
         pokemons : res.data.results
        }))
    }
  }
</script>

We can see we do asyncData () on the same page. Of course, if the data is only a little and used only on this page, it does not matter. but if we want to use the data in other components and the component has more components, this will be a problem from memory, speed, and maintenance.

Use Vuex in Nuxt.js

When we install Nuxt.js we have automatically installed Vuex, So we do not need to install anymore. We will create an index.js file in the store folder. Index.js is responsible for loading all required data. There are two ways of writing Vuex you can see it in the documentation https://nuxtjs.org/guide/vuex-store. I will apply every way of writing in a real application.

1. Classic mode

This way of writing that I often use the first time using Vuex, because it is simple and becomes more centralized files but over time I find it difficult when I want to separate the codes that are still in use and which are not used. in the Classic Mode we have to create an instance of Vuex.store () and save it into a variable then we export the variable.

Code:

import axios from '~/plugins/axios'
import Vuex from 'vuex'
const pokeStore = () => {
  return new Vuex.Store({
    state: {
      pokemons: []
    },
    mutations: {
      setPokemons (state, items) {
        state.pokemons = items
      }
    },
    actions:{
        async nuxtServerInit ({commit}){
        const {data} = await axios.get('pokemon')
        commit('setPokemons', data.results)
        }   
    }
  })
}
export default pokeStore
  • Because we are going to create a Vuex instance, we need to import Vuex import Vuex from 'vuex'

  • to import the axios instance we have created in the previous tutorial import axios from '~/plugins/axios'

  • state: {} is the data or variable that we have declared. pokemons: [] is the data we have declared in the form of arrays.

  • mutations: {} have the ability to change data in state: {}. mutation will be called in action: {}. setPokemon () is the name of the mutation function, This function has two parameters.

    • state is a mandatory parameter that must exist in the mutation function.

    • items is an optional parameter or value we will use to change the state value. We can access existing data in state by using state.NameOfState.

  • action: {} is an intermediary call a mutation. in action we can create a function() that we can call in the event or any other. Example : V-on:click="functionName()".

    • nuxtServerInit () will automatically run when we load the application. so we do not have to write the function in thecreated ()or mounted (). nuxtServerInit() is a method provided by Nuxt.js not vue.js. Every function listed in the action: {} will receive a useful {commit} parameter to commit to the function inmutations: {}. in this method, we will commit to the setPokemon() and pass the results from the API data we have taken with Axioscommit('setPokemons', data.results).

Use the data in Component
We have created the data section. to extract the data we need to import mapState(), then we put the data in computed property: {} to get updated data. then we enter the variable name in the state: {}

<template>
  <section class="container">
    <div style="text-align: center;">
      <app-logo/>
      <h1 class="title">
        millenuxt
      </h1>
      <h2 class="subtitle">
        tutorial
      </h2>
    </div>
    <div class="list-group">
        <a href="#" class="list-group-item list-group-item-action active">
          List data from API
        </a>
        <a v-for="item in pokemons" :key="item.name" href="#" class="list-group-item list-group-item-action">{{item.name}}</a>
    </div>
  </section>
</template>
<script>
  import {mapState} from 'vuex'
  export default{
    computed: mapState([
      'pokemons'
      ])
  }
</script>

to see the result we can run npm run devon our project and we will see results like this
dusktitutor4.gif

2. Moduls mode

Modules mode allows us to separate each of our Vuex files, making it easier for us to maintain our app. but on the other hand, we will have many files. for me from coding side modules mode more elegant and neat. in modules mode we will export each state, mutations, and action respectively. we also do not need to import Vuex.

Code:

import axios from '~/plugins/axios'
export const state = () => ({
    pokemons : []
});
export const mutations = {
    setPokemons(state, items){
        state.pokemons = items
    }
}
export const actions = {
    async nuxtServerInit ({commit}){
        const {data} = await axios.get('pokemon')
        commit('setPokemons', data.results)
    }
}

Not much different from Classic mode, just a different way of writing. We no longer create a Vuex instance. If in classic mode we export Vuex instance then in modules mode we export state, action, and mutation one by one.

  • to import the Axios instance we have created in the previous tutorial import axios from '~/plugins/axios'
  • We export state, mutations, and actions in a const.
    • state is a mandatory parameter that must exist in the mutation function.

    • items is an optional parameter or value we will use to change the state value. We can access existing data in the state by using state.NameOfState.

Use the data in Component
to display data we do not need to change anything in its component parts. We can see the result there will be no difference when the code is executed.

<template>
  <section class="container">
    <div style="text-align: center;">
      <app-logo/>
      <h1 class="title">
        millenuxt
      </h1>
      <h2 class="subtitle">
        tutorial
      </h2>
    </div>
    <div class="list-group">
        <a href="#" class="list-group-item list-group-item-action active">
          List data from API
        </a>
        <a v-for="item in pokemons" :key="item.name" href="#" class="list-group-item list-group-item-action">{{item.name}}</a>
    </div>
  </section>
</template>
<script>
  import {mapState} from 'vuex'
  export default{
    computed: mapState([
      'pokemons'
      ])
  }
</script>

diskitutor5.gif


We will see results that are not much different from between Classic mode and Modules mode. we can still see the data coming from the API successfully in the show well.

Conclusion

We have learned how to use Vuex and learn how to write using Classic mode and Modules mode. state:{} is a collection of data that we will use in our application, mutation:{} is used to change the value of existing data in state, but the mutation cannot be executed directly, the mutation must be on the call and committed to action:{}.

Curriculum

Learn Nuxt#1 Nuxt structure, Global CSS, Request API

Proof of Work Done

https://github.com/milleaduski/learnNuxtjs

Sort:  

Thank you for your contribution.
While I liked the content of your contribution, I would still like to extend one advice for your upcoming contributions:

  • Structure of the tutorial: Improve the structure of the tutorial.

Looking forward to your upcoming tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Hey @duski.harahap
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 63688.35
ETH 3125.30
USDT 1.00
SBD 3.97