Vuex和全局变量
关于全局对象和 Vuex 之间的区别,官方写得还是比较通俗易懂的:
Vuex 和单纯的全局对象有以下两点不同:
1.Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2.你不能直接改变 store 中的状态。改变 store 中状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
3,vuex必要的两个东西:state和mutation
state用来存储状态数据,mutation用来操作state
4,vuex非必要的三个东西:action,getter和module
action用来进行额外的异步操作,内部还是会调用mutation来变更state
getter用来包装一层state,获取基于state的包装状态
当状态数据庞大且复杂的时候,module用来划分不同类型的state
vuex使用
1,读取
实例化vue的时候,可以将store全局注入到vue中
new Vue({
store
})
于是可以在每个组件中,通过调用this.$store.state.xxx来获取某个状态
2,getter
将state进行包装(类似计算属性)
state:{
date:new Date()
}
getters:{
//可以对state进行第一层包装
weekDate:state=>{
retuen state.date.getWeek()
}
//也可以对getters内部进行封装
deepDate:(state,getters)=>{
return func(getters.weekDate)
}
}
**getter可以跟state一样在组件内部被使用
computed:{
weekDate(){
return this.$store.getters.weekDate
}
}
**高级用法,给getter传参,只要让getters对应的属性是个函数就行了
getters:{
weekDate:state=>fm=>{
return func(state.Date,fm)
}
}
//使用
this.$store.getters.weekDate('xxx')
Mutation
vuex规定不能直接设置state的值,必须显示使用mutation
state:{
counter:0
}
//定义mutations
mutations:{
addCounter(state,n){
state.counter+=n
}
}
//提交mutaion以变更state
store.commit('addCounter',10)
//另一种commit方式
store.commit({
type:'addCounter',
n:10
})
action
action用来异步更新状态,内部提交的还是mutation
state:{
count:0
}
mutations:{
increment(state){
state.count++
}
},
actions:{
//这里的context类似state,可以拿到state,commit,getters
incerment(context){
//do some ajax
context.commit('increment')
}
}
**分发action
store.dispatch('increment')
dispatch还可以处理promise返回
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
//分发
store.dispatch('actionA').then(()=>{
//....
})
mapState
其实是使用state的语法糖
之前
computed:{
a(){
return store.state.a
}
b(){
return store.state.b
}
}
之后
import {mapstate} from 'vuex'
computed:{
loaction(){},
...mapState({
'a',
'b'
})
}
mapGetters
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
// 将 `this.increment()` 映射为
// `this.$store.commit('increment')`
'increment',
// `mapMutations` 也支持载荷:
// 将 `this.incrementBy(amount)` 映射为
// `this.$store.commit('incrementBy', amount)`
'incrementBy'
]),
...mapMutations({
// 将 `this.add()` 映射为
// `this.$store.commit('increment')`
add: 'increment'
})
}
}
mapActions
同上
Module
如果state管理的数据涉及的业务复杂多变,可以按模块来划分,便于代码维护
将store分割成拥有state,getters,mutatons,actions的部分,每个部分拥有不同的业务功能划分的内容,这就是模块的作用
且模块可以嵌套
**使用module
import moduleA from './module/moduleA';
import moduleB from './module/moduleB';
export default new Vuex.Store({
modules: {
moduleA, moduleB,
},
// ...
}
在组建中
import {mapState, mapMutations} from 'vuex';
export default {
computed: {
...mapState({
name: state => (state.moduleA.text + '和' + state.moduleB.text)
}),
},
methods: {
...mapMutations(['setText']),
modifyNameAction() {
this.setText();
}
},
}