准备
安装
Vuex
, 是Vue官方出的package, 它不是Vue内置的。需要另外安装。
npm install vuex --save
然后,需要在应用启动文件启用Vuex
。
main.js
import Vue from 'vue';
import Vuex from 'vues';
import App from 'App.vue';
Vue.use(Vuex);
new Vue({
el: '#app',
render: h => h(app)
});
创建一个Store
store.js
export const store = new Vuex.store({
state: {
safelyStoredNumber: 0
}
});
为了使用这个store你必须在你所有要使用其的component里面import这个store。 或者你可以将它注入到跟Vue实例中,这样应用的其他组件都可以使用这个store了。
main.js
import Vue from 'vue';
import Vuex from 'vuex';
import App from 'App.vue';
import { store } from './store.js';
Vue.use(Vuex);
new Vue({
store,
el: '#app',
render: h => h (App)
});
访问State
下载创建getter
来从store中读取数据。
使用Getters
在store中getter是一个简单的函数,它接收一个state对象返回它的一个值。在component中,可以通过this.$store.getters.property
做为一个计算属性(不是函数)来获取。如果getter需要接受一个参数,可以返货一个接受参数的函数。
store.js
export const store = new Vuex.store({
state: {
safelyStoredNumber: 0
},
getters: {
safelyStoredNumber: state => state.safelyStoredNumber,
storedNumberMatches(state) {
return matchNumber => {
return state.safelyStoredNumber === matcheNumber;
}
}
// 简写
storedNumberMatches: state => matchedNumber => state.safelyStoreNumber === matcheNumber
}
});
在components最简单的访问getters的方法是通过Vuex的mapGetters方法。它让你可以在component中直接使用safelyStoreNumber
而不是this.$store.getters.safelyStoreNumber
。
App.vue
<template>
<p>The safely stored number: {{safelyStoredNumber}}</p>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
'safelyStoredNumber'
])
}
}
</script>
修改state
Synchronous Mutations
调用mutation
的函数来修改state。mutation接受一个当前的state和一个可选的payload。payload可以是任何对象。mutation
必须是同步的,并且不应该返回任何值。使用this.$store.commit('mutationName', payload)
来调用mutation。
store.js
export const store = new Vuex.Store({
state: {
safelyStoredNumber: 0
},
...
mutations: {
incrementStoredNumber(state) {
state.safelyStoredNumber++;
},
setStoredNumber(state, newNumber) {
state.saftlyStoredNumber = newNumber;
}
}
});
和getters一样,Vuex有一个使用mutation
的简便方法,那就是mapMutations
方法。
App.vue
<template>
<p>The safely stored number: {{safelyStoredNumber}}</p>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
...
methods: {
...mapMutations([
'incrementStoredNumber',
'setStoredNumber'
])
}
}
</script>
异步Actions
在一些复杂的应用中,你可能需要执行一些异步方法来修改state。Vues使用actions
来处理这个。action
接受一个state context,使得在action里面可以访问getter和commit mutations。
action最好(非必需)是返回一个Promise指明完成状态。使用ES2017的async/await,可以轻松的检出async action。在component中通过this.$store.dispatch('actionName', payload).then(response => {})
使用action。
在action中通过context.commit('mutationName', payload)
修改state。
store.js
import myRemoteService from './my-remote-service.js'
export const store = new Vuex.store({
state: {
safelyStoredNumber: 0
},
...
actions: {
async setNumberToRemoteValue(context) {
// commit 'setStoredNuymber' mutation
context.commit('setStoredNumber', await myRemoteService.getRemoteValue());
return Promise.resolve();
},
}
});
和getters一样,Vuex有一个使用action
的简便方法,那就是mapActions
方法。
App.vue
<template>
<p> The safely stored number: {{safelyStoredNumber}}</p>
</template>
<script>
import { mapActions } from 'vuex'
export default {
...
methods: {
...mapActions([
'setNumberToRemoteValue',
])
}
}
</script>
模块化
随着actions,mutations, getters越来越多你需要按照模块来分割它们。Vuex提供了Modules来实现这个。
my-store-module.js
export const myModule = {
// This makes your getters, mutations, and actions accessed by, eg: 'myModule/myModularizedNumber' instead of mounting getters, mutations, and actions to the root namespace.
namespaced: true,
state: {
myModularizedNumber: 0
},
getters: {
myModularizedNumber: state => state.myModularizedNumber
},
mutations: {
setModularizedNumber(state, newNumber) {
state.myModularizedNumber = newNumber
}
}
}
store.js
import { myModule } from './my-store-module.js';
export const store = new Vuex.store({
modules: {
myModule
},
state: {
safelyStoredNumber: 0
},
...
});
mapGetters
, mapMutations
, mapActions
可以接受第一个参数来标明module的命名空间。
...mapGetters([
'myModule/nestedModule/subNestedModule/exampleGetter',
'myModule/nestedModule/subNestedModule/anotherGetter',
])
可以使用上面的代码来替代上面的代码:
...mapGetters('myModule/testedModule/subNestedModule', [
'exampleGetter',
'anotherGetter'
])