什么是VueX
VueX
是专门服务于Vue.js
的状态管理模式
,大白话就是Vue项目中有一些全局变量,这些变量每个地方都可以用也可以修改,VueX
负责把这些变量以及修改变量的方法包装起来,这样会更规则。
VueX
应用的核心就是store
仓库,项目中要使用VueX
,先需要安装
npm install vuex
然后在src文件夹下创建store
store.jpgstore的组成
const mystore = new VueX.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
getters: {
getCount(state) {
return state.count.toFixed(2)
}
},
actions: {
incrementAsync({ commit }) {
new Promise(resolve => {
setTimeout(() => commit('increment'),100)
})
}
}
})
上面是一个简单的store
,state
对象里面的东西就是'全局变量',mutations
对象里面则包含的是改变这些全局变量的方法,getters
和actions
下面再讲
store的使用
Vue项目中怎样才能使用到这个store
呢,首先在index.js
中导出store
export default mystore
然后在main.js
引入,并将它注入到每一个组件中
import store from './store/index'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
此时在组件中,可以通过this.$store
访问到store
computed: {
count () {
return this.$store.state.count
}
}
也可以用mapState函数
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
Getter
有时候需要把从state
中派生一些状态,譬如toFixed(2)
,所以出现了getter
对象,
通过getter
获取状态用辅助方法mapGetters
import { mapGetters } from 'vuex'
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'getCount'
// ...
])
}
Mutation
更改store
中状态的唯一方法就是提交mutation
,提交方法store.commit('increment',payload)
,payload
可以是对象也可以是单个的值
注意:mutation必须是同步函数
在组件中提交mutation
使用this.$store.commit()
methods: {
updateCount(payload) {
this.$store.commit('increment',payload)
}
}
组件中使用
<div @click="updateCount(payload)"></div>
通过mapMutations
辅助函数
import { mapMutations } from 'vuex'
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
组件中使用
<div @click="increment(payload)"></div>
或者
<div @click="add(payload)"></div>
Action
因为Mutation
必须是同步函数,如果要异步修改store
的状态就需要Action
。
Action
的特点
- Action 提交的是 mutation,而不是直接变更状态
- Action 可以包含任意异步操作。
在组件中分发Action
使用this.$store.pitch()
this.$store.pitch('incrementAsync')
使用mapActions
辅助函数
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
Module
当我们需要的状态比较多的时候,store
对象就会变得非常臃肿,因此我们可以把store分割成模块。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
export default new Vuex.Store({
modules: {
moduleA,
moduleB,
moduleC
}
})
上面代码中,我们把moduleA,moduleB,moduleC
都曝露于外,在组件中我们可以用mapState,mapActions,mapGetters,mapActions
获取全部的state,action,getter,action
,但是如果又的模块的属性和方法名相同,那么使用它将会出现冲突,所以需要加入命名空间
.
const moduleA = {
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
这样在组件中使用必须带上模块的名称
...mapState({
'amount': 'moduleA/amount'
})
差不多就这样,收工...
网友评论