vue-cli搭建的專案中使用vuex實現狀態管理
阿新 • • 發佈:2019-01-10
1、安裝
使用vue-cli搭建好專案以後,安裝vuex
npm install vuex --save-dev
2、建立Vuex.Store例項
對於大型應用,需要儲存的狀態可能很多,我們就將store中的state、getters 、mutations 和 actions分割到單獨的檔案中。並且把 Vuex 相關程式碼分割到模組中。
在專案的src資料夾下建立一個名為store的資料夾,store資料夾下的檔案目錄如下所示:
src/store/index.js 檔案是組裝模組並匯出store的地方
import Vue from 'vue'; import Vuex from 'vuex'; import state from './state.js'; import getters from './getters.js'; import mutations from './mutations.js'; import actions from './actions.js'; import modules from './modules/modules.js'; Vue.use(Vuex); const store = new Vuex.Store({ state, getters, mutations, actions, modules }); export default store;
3、state.js
const state = {
count: 0,
number: 0,
username: 'liu',
nickname: 'never',
password: 123
};
export default state;
4、getters.js
const getters = { message: state => { return '使用者名稱為:' + state.username; }, msg: state => { return `暱稱為:${state.nickname}`; // 等價於 return '暱稱為:' + state.nickname; // `${}` 是ES6中的模版字串語法 } }; export default getters;
5、mutations.js
const mutations = { increment: state => { state.count++; }, asnyAdd: state => { state.number++; }, changePassword: (state, payload) => { state.password = payload.password; }, changeNickname: (state, payload) => { state.nickname = payload.nickname; } }; export default mutations;
6、actions.js
const actions = {
asnyAdd: context => {
context.commit('asnyAdd');
},
changeNickname ({commit}, payload) {
commit('changeNickname', payload);
}
};
export default actions;
7、在Vue元件中使用
<template>
<div>
<h1>{{study}}</h1>
<button @click="increment">同步加1</button>
<button @click="asnyAdd">非同步加1</button>
<button @click="changePassword({password: 123456})">同步修改密碼</button>
<button @click="changeNickname({nickname: 'sleepwalker'})">非同步修改暱稱</button>
<p>count:{{count}}</p>
<p>number:{{number}}</p>
<p>username:{{username}}</p>
<p>nickname:{{nickname}}</p>
<p>password:{{password}}</p>
<p>{{message}}</p>
<p>{{msg}}</p>
</div>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
export default {
data () {
return {
study: 'vuex-study'
};
},
computed: {
...mapState(['count', 'number', 'username', 'nickname', 'password']),
...mapGetters(['message', 'msg'])
},
methods: {
...mapMutations(['increment', 'changePassword']),
...mapActions(['asnyAdd', 'changeNickname'])
}
};
</script>
8、modules
(1)modules.js
import moduleA from './moduleA.js';
import moduleB from './moduleB.js';
const modules = {
moduleA,
moduleB
};
export default modules;
(2)moduleA.js
// 預設情況下,模組內部的 action、mutation 和 getter 是註冊在全域性名稱空間的
// 模組的狀態預設註冊在全域性名稱空間,為一個物件,物件中的屬性是模組中的狀態
const moduleA = {
state: {
countA: 1,
nameA: 'moduleA'
},
// 模組內部的 mutation 和 getter,接收的第一個引數是模組的區域性狀態物件。
getters: {
// 這裡的 state 物件是模組的區域性狀態
msgA: state => {
return `模組A的名稱為:${state.nameA}`;
},
// 對於模組內部的 getter,根節點狀態作為第三個引數(rootState)暴露出來
msgTotal: (state, getters, rootState) => {
return `根節點使用者名稱為:${rootState.username},模組A的名稱為:${state.nameA}`;
}
},
// 在模組的muatations中不能使用根節點狀態,因為muatations中是同步更新狀態
mutations: {
addA (state) {
state.countA++;
}
},
// 對於模組內部的 action,區域性狀態通過 context.state 暴露出來,根節點狀態則為 context.rootState
actions: {
asnyAddA (context) {
context.commit('addA');
console.log('區域性狀態countA為:' + context.state.countA);
console.log(context.rootState); // 根節點狀態是一個物件
console.log('根節點狀態count為:' + context.rootState.count);
}
}
};
export default moduleA;
(3)在Vue元件中使用moduleA中的狀態
moduleA.vue
<template>
<div>
<h1>{{study}}</h1>
<button @click="addA">同步加1</button>
<button @click="asnyAddA">非同步加1</button>
<p>countA:{{moduleA.countA}}</p>
<p>nameA:{{moduleA.nameA}}</p>
<p>{{msgA}}</p>
<p>{{msgTotal}}</p>
</div>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
export default {
data () {
return {
study: 'vuex-module-study'
};
},
computed: {
...mapState(['moduleA']),
...mapGetters(['msgA', 'msgTotal'])
},
methods: {
...mapMutations(['addA']),
...mapActions(['asnyAddA'])
},
mounted () {
console.log(this.$store.state.moduleA); // 是一個物件
console.log('moduleA.countA:' + this.$store.state.moduleA.countA);
console.log(this.$store.getters.msgA);
console.log(this.$store.getters.msgTotal);
}
};
</script>
(4)moduleB.js
const moduleB = {
state: {
countB: 1,
nameB: 'moduleB'
},
getters: {
msgB: state => {
return `模組B的名稱為:${state.nameB}`;
}
},
mutations: {
addB (state) {
state.countB++;
}
},
actions: {
asnyAddB ({ state, commit, rootState }) {
commit('addB');
console.log('區域性狀態countB為:' + state.countB);
console.log('根節點狀態count為:' + rootState.count);
}
}
};
export default moduleB;
(5)在Vue元件中使用moduleB中的狀態
moduleB.vue
<template>
<div>
<h1>{{study}}</h1>
<button @click="addB">同步加1</button>
<button @click="asnyAddB">非同步加1</button>
<p>countB:{{moduleB.countB}}</p>
<p>nameB:{{moduleB.nameB}}</p>
<p>{{msgB}}</p>
</div>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
export default {
data () {
return {
study: 'vuex-module-study'
};
},
computed: {
...mapState(['moduleB']),
...mapGetters(['msgB'])
},
methods: {
...mapMutations(['addB']),
...mapActions(['asnyAddB'])
}
};
</script>