文章で説明するより、コードを見たほうが早いと思うのでまずはコードを見てください。
内容としては、isLoggedというstateをloginしたらture、logoutしたらfalseをに変更させるだけです。それをmoduleで分けています。
コード
store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import {auth} from './modules/auth';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
auth,
},
});
store/modules/auth
export const auth = {
namespaced: true,
state: {
isLogged: false
},
mutations: {
changeIsLogged(state, isLogged){
state.isLogged = isLogged;
}
},
actions: {
login(authData){
this.commit('auth/changeIsLogged', true);
},
logout(){
this.commit('auth/changeIsLogged', false);
}
}
}
main.jsに以下のコードを追加
import store from './store/';
components/Header.vue
export default {
name: 'Header',
data() {
return {
}
},
computed: {
auth: function () {
return this.$store.state.auth;
}
},
methods: {
logout() {
this.$store.dispatch('auth/logout');
},
login() {
this.$store.dispatch('auth/login');
}
}
};
注意点
module内のdispatchやcommitを使う場合はpathにmodule名も含める必要がある。
例
this.commit('module名/changeIsLogged', true);
this.$store.dispatch('module名/login');
検知してくれない問題
修正前
this.$store.dispatch('auth/login');
や this.$store.dispatch('auth/logout');
などを実行するとvuexのactionが呼ばれてstateが変更されます。
しかしその変更がcompornents内で検知されない場合はあります。
例
computed: {
isLogged: function () {
return this.$store.state.auth.isLogged;
}
},
テストの為にtemplateに{{ isLogged }}
を追加してisLoggedが変更されるか確認しています。
修正後
変更の検知をするパターン1
this.$store.stateまでにしておく(stateの後に.
で繋がないようにする。ただしmoduleを使っている場合はmodule名までは書いて大丈夫)。
computed: {
auth: function () {
return this.$store.state.auth;
}
},
そして{{ auth.isLogged }}
みたいな感じで呼び出します。
変更の検知をするパターン2
mapStateを使うパターン
computed: {
...mapState({
isLogged: state => state.auth.isLogged
})
},
実際にはmapStateを使うほうが一般的だと思います。
アンチパターン
vuexの場合、データの受け渡しをvuexだけで完結したいので、以下のようにdata内でstateを呼び出してしまうとmethodなので値を変更出来てしまうのでよくありません。
data() {
return {
isLogged: this.$store.state.auth
}
}
なのでstateを呼び出すときは、以下のようにcomputedを使うべきです。
computed: {
auth: function () {
return this.$store.state.auth;
}
},
以上です。
もっとこうした方が良いなどありましたら教えていただきたいです。