vuex为状态管理器,主要用于全局状态管理,方便组件间的状态共享。其主要涉及Store、Mutation、Action、Getter
vuex思想:
通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态的独立性,代码更结构化且更易维护。
state:用来数据共享数据存储
mutation:用来注册改变数据状态
getters:用来对共享数据进行过滤操作
action:解决异步改变共享数据
state 驱动应用的数据源 view 以声明方式将state映射到视图 actions 响应在view上的用户输入导致的状态变化
每一个vuex应用的核心就是store仓库,即一个容器,其包含着应用中的大部分的状态state。
vuex的状态存储是响应式的:当vue组件从store中读取状态时,若store中的状态发生变化,则相应的组件也会相应地得到高效更新。
不能直接改变store中的状态:改变store中状态的唯一途径即是显示地提交mutation。
state:
vuex使用单一状态树,即一个对象包含了全部的应用层级状态,唯一数据源,每一个应用仅包含一个store实例。
vuex状态存储是响应式的,从store实例中读取状态最简单方法是在计算属性中返回某个状态:
Getter:
getter的返回值会根据它的依赖被缓存起来,只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({
state:{
todos:[
{id:1, text:'dd', done:true},
{id:2, text:'d2d', done:false}
]
},
getters:{
doneTodos:state => {
return state.todos.filter(todo => todo.done)
}
}
})
通过属性访问:store.getters.doneTodos,getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的
通过方法访问:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果
getters:{
getTodoById:(state)=>(id)=>{
return state.todos.find(todo=>todo.id===id)
}
}
store.getters.getTodoById(2)
mapGetters辅助函数:仅是将 store 中的 getter 映射到局部计算属性
import {mapGetters} from 'vuex';
export default {
computed:{
...mapGetters(['count','amount'])
}
}
ps:若将getter属性领取一个名字,使用对象形式:
mapGetters({
count:newCount
})
mutation:
更改vuex的store中的状态的唯一方法是提交mutation,每个mutation都有一个字符串的事件类型type和一个回调函数handler,
handler即是实际进行状态更改的地方,且接受state作为第一个参数。
ps: 最好提前在store中初始化所有所需属性;新添加属性如想具有响应式,则推荐使用Vue.set(obj,'newProp,123)或 vm.$set(target,key,value)或者以新对象替换老对象,
如state.obj={...state.obj, newProp:123}
mutation 必须是同步函数
action
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state){
state.count++
}
},
actions:{
increment(context){
context.commit('increment')
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters
来获取 state 和 getters。
Action 通过 store.dispatch 方法触发:store.dispatch('increment')
store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise
一个 store.dispatch 在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用非常复杂时,store会很臃肿。=》出现了将store分割成module,每个module拥有自己的state/mutation/action/getter及
子模块。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
computed:{
...mapGetters(['memberInfo'])
},
methods:{
...mapActions(['GetInfo', 'GetShopList']),
}
// state
// getters 批量导出state中的值
// action提交mutation
// store.dispatch触发action操作
参考 & 感谢:vuex官网 & 各路大神