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 } })