Vue – vuex

vuex

vuex is state management pattern.
This idea is from flux.
vuex supports flux idea like redux.

Application contains Action, State, View. Action effects State, State updates View, View effects Action. This is circle.

This is vuex concept.

Roles

Name Description
state
getter
mutation
action

vuex prepares support features mapGetters, mapState, mapMutations, mapAction

Sample Application

This is super simple sample(not for production).
Use vuex basic features.
To create this sample, I use vue-cli and vue-router.

vue init webpack vuex2
cd vuex2
npm install

Install vuex

npm install --save vuex

If you are not familiar with vue-cli, please read my previous post(Vue – vue-cli)

Ready to start!!!
In this sample, I prepared textbox and button and space to show textbox value.
Press button and show value on space. this value and space value managed by vuex store.

Project Structure

This is vue-cli project I show you parts of change

src
|- components
|    |- FieldInput.vue
|    |- MsgDiv.vue
|    |- Page.vue
|- router
|    |- index.js
|- store
|    |- index.js
|- App.vue
|- main.js

Replace current HelloWorld to Page

Page.vue

<template>
  <div>
    <FieldInput></FieldInput>
    <button v-on:click="clickAction">Click me!</button>
    <MsgDiv></MsgDiv>
  </div>
</template>

<script>
import FieldInput from '@/components/FieldInput'
import MsgDiv from '@/components/MsgDiv'
import { mapActions } from 'vuex'

export default {
  name: 'Page',
  date() {
    return {
      message : ''
    }
  },
  methods: {
    ...mapActions('Page', {
      'clickAction': 'clickAction'
    })
  },
  components: {
    FieldInput,
    MsgDiv
  }
}
</script>

<style>
</style>

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
//import HelloWorld from '@/components/HelloWorld'
import Page from '@/components/Page'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Page',
      component: Page
    }
  ]
})

Page becomes page root.

And Page includes FieldInput and MsgDiv component inside.

Components

components/MsgDiv.vue

<template>
  <div>{{msg}}</div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'MsgDiv',
  /*
  data() {
    return {
      msg : ''
    }
  }*/
  computed: {
    ...mapGetters('MsgDiv', {
      'msg': 'getMsg'
    })
  }
}
</script>

<style>
</style>

components/FieldInput.vue

<template>
  <input type="text" v-model="msg"/>
</template>

<script>

export default {
  name: 'FieldInput',/*
  data() {
    return {
      msg : ''
    }
  },*/
  computed: {
    msg: {
      get() {
        return this.$store.state.msginput;
      },
      set(value) {
        this.$store.commit('setMsgInput', value);
      }
    }
  }
}
</script>

<style>
</style>

Store

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import router from '../router'

Vue.use(Vuex)

const Page = {
  namespaced: true,
  state: {

  },
  mutations: {
  },
  actions: {
    clickAction({commit, state, rootState}) {
      console.log('click me');
      commit('setMsg', rootState.msginput, {root:true});
    }
  }
}

const FieldInput = {
  namespaced: true,
  state: {

  },
  mutations: {

  },
  actions: {

  }
}

const MsgDiv = {
  namespaced: true,
  state: {

  },
  mutations: {

  },
  actions: {

  },
  getters: {
    getMsg(state, getters, rootState) {
      return rootState.msg;
    }
  }
}


export default new Vuex.Store({
  state: {
    msginput: '',
    msg: ''
  },
  mutations: {
    setMsg(state, value) {
      state.msg = value;
    },
    setMsgInput(state, value) {
      state.msginput = value;
    }
  },
  actions: {

  },
  getters: {

  },
  modules: {
    Page,
    FieldInput,
    MsgDiv
  }
})

Ref

vue.js + Vuexチュートリアル
Core Concepts – Vuex