Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.
你可以简单理解为, 这是一个全局状态下的data, 任何组件可以访问这里面的数据.
两个特点:
import Vue from 'Vue'
import Vuex from 'Vuex'
Vue.use(Vuex)
const store = new Vuex({
state: {
count: 0,
txt1: 'hello',
txt2: 'world'
},
// getters 简单理解就是computed属性
getters:{
txtLink(state){
return state.txt1 + state.txt2
},
// getter作为第二个参数
txtLinkLength(state,getters){
return getters.txtLink.length
}
},
// mutation 只能同步操作
mutations:{
increment(state){
state.count++
},
// 带参数
increment1(state,n){
state.count+=n
},
// 参数是对象
increment2(state,obj){
console.log(obj)
},
},
// 通过action可以异步操作
actions: {
// 这里context可以代指store,但不是store
increment (context) {
// 可以通过context获取 state 和 getters里的数据
// const count = context.state.count
// const txtLink = context.getters.txtLink
context.commit('increment')
},
// 异步 {commit} 解构 context.commit
// params 是传入的参数,可以是对象,字符串等
incrementAsync({commit, state}, params){
setTimeout(()=>{
commit('increment')
},1000)
},
// Promise
actionA({commit}){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
commit('increment')
resolve()
},1000)
})
},
// action里面调用异步action
actionB({commit,dispatch}){
dispatch('actionA').then(res=>console.log(res))
},
// async await
// getData(),getOtherData() 是 Promise
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
})
new Vue({
el: '#app'
store,
})
// 1. state 使用
{{$store.state.count}}
{{count}} // 可以用计算属性接收,页面简洁一些
// 2. getters 使用
{{$store.getters.txtLink}}
const moduleA = {
state: () => ({
count:0
}),
mutations: {
increment(state){
state.count++
}
},
actions: {
incrementSync({commit}){
commit('increment')
}
},
getters: {
countGetter(state){
return state*2
}
}
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
// 组件内使用各种状态
// a模块state
store.state.a.count
// a模块getters
store.getters.a.count
// a模块mutations
store.commit('a/increment')
// a模块mutations
store.dispatch('a/incrementSync')
store.state.b // -> moduleB 的状态 ...
const moduleA = {
state: () => ({
count: 0
}),
mutations: {
increment (state) {
// 这里的 `state` 对象是模块的局部状态
state.count++
}
},
// 对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:
getters: {
doubleCount (state,getters,rootState) {
return state.count + rootState.count
}
},
actions: {
increment ({ state, commit, rootState }) {
// rootState 是根节点的状态
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
modules: {
foo: {
namespaced: true,
getters: {
// 在这个模块的 getter 中,`getters` 被局部化了
// 你可以使用 getter 的第四个参数来调用 `rootGetters`
someGetter (state, getters, rootState, rootGetters) {
getters.someOtherGetter // -> 'foo/someOtherGetter'
rootGetters.someOtherGetter // -> 'someOtherGetter'
},
someOtherGetter: state => { ... }
},
actions: {
// 在这个模块中, dispatch 和 commit 也被局部化了
// 他们可以接受 `root` 属性以访问根 dispatch 或 commit
someAction ({ dispatch, commit, getters, rootGetters }) {
getters.someGetter // -> 'foo/someGetter'
rootGetters.someGetter // -> 'someGetter'
dispatch('someOtherAction') // -> 'foo/someOtherAction'
dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
commit('someMutation') // -> 'foo/someMutation'
commit('someMutation', null, { root: true }) // -> 'someMutation'
},
someOtherAction (ctx, payload) { ... }
}
}
}
{
actions: {
// 这里是全局的action
someOtherAction ({dispatch}) {
dispatch('someAction')
}
},
modules: {
foo: {
namespaced: true,
actions: {
someAction: {
root: true, // 添加 root 属性变成全局actions
handler (namespacedContext, payload) { ... } // -> 'someAction'
}
}
}
}
}
computed: {
...mapState({
a: state => state.some.nested.module.a,
b: state => state.some.nested.module.b
})
},
methods: {
...mapActions([
'some/nested/module/foo', // -> this['some/nested/module/foo']()
'some/nested/module/bar' // -> this['some/nested/module/bar']()
])
}
// 简写
computed: {
...mapState('some/nested/module', {
a: state => state.a,
b: state => state.b
})
},
methods: {
...mapActions('some/nested/module', [
'foo', // -> this.foo()
'bar' // -> this.bar()
])
}
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
export default {
computed: {
// 在 `some/nested/module` 中查找
...mapState({
a: state => state.a,
b: state => state.b
})
},
methods: {
// 在 `some/nested/module` 中查找
...mapActions([
'foo',
'bar'
])
}
}
import Vuex from 'vuex'
const store = new Vuex.Store({ /* 选项 */ })
// 注册模块 `myModule`
store.registerModule('myModule', {
// ...
})
// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
// ...
})
const moduleA = {
state: () => ({
count:0
}),
mutations: {
increment(state){
state.count++
}
},
actions: {
incrementSync({commit}){
commit('increment')
}
},
getters: {
countGetter(state){
return state*2
}
}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
// 组件内使用各种状态
store.state.a.count
store.getters.a.count
store.commit('increment') // 这里路径就不是a/increment了
store.dispatch('incrementSync')
const moduleA = {
namespaced: true,
state: () => ({
count:0
}),
mutations: {
increment(state){
state.count++
}
},
actions: {
incrementSync({commit}){
commit('increment')
}
},
getters: {
countGetter(state){
return state*2
}
},
moduleB{
...
}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
// 组件内使用各种状态
store.state.a.count
store.getters.a.count // 这里路径就要加上模块路径了
store.commit('a/increment') // 这里路径也要加上模块路径了
store.dispatch('a/incrementSync')
- PS :如果模块A 里面再次嵌套b模块
a和b模块都带命名空间
store.state.a.b.count
store.getters.a.b.count1 // 这里路径就要加上模块路径了
store.commit('a/b/increment1') // 这里路径也要加上模块路径了
store.dispatch('a/b/incrementSync1')
a模块带命名空间b模块不带命名空间(getter,metations 和actions的使用路径会依次提升,提升到有命名空间的模块时会停止,如果都没有命名空间则会上升到根状态上调用,如果上升过程中发现有重复的命名,会报错 duplicate getter key: xxx)
store.state.a.b.count
store.getters.a.count1
store.commit('a/increment1')
store.dispatch('a/incrementSync1')
应用层级的状态应该集中到单个 store 对象中。
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
异步逻辑都应该封装到 action 里面。
mutations:{
ADD(state,payload){
}
}
actions:{
ADD(context,payload){
}
}
// 解构
actions:{
ADD({state,commit,dispatch,getters},payload){
}
}
{
state, // 等同于 `store.state`,若在模块中则为局部状态
rootState, // 等同于 `store.state`,只存在于模块中
commit, // 等同于 `store.commit`
dispatch, // 等同于 `store.dispatch`
getters, // 等同于 `store.getters`
rootGetters // 等同于 `store.getters`,只存在于模块中
}
state, // 如果在模块中定义则为模块的局部状态
getters, // 等同于 store.getters
state, // 如果在模块中定义则为模块的局部状态
getters, // 等同于 store.getters
rootState // 等同于 store.state
rootGetters // 所有 getters
{
key: {
state,
namespaced?,
mutations,
actions?,
getters?,
modules?
},
...
}
dispatch(type: string, payload?: any, options?: Object): Promise
dispatch(action: Object, options?: Object): Promise
更多详情请参阅文档
Vuex官方链接