基本原理
vue中store参数,Vuex插件初始化时会为每一个vue实例添加Vuex.Store实例。Vuex.Store实例存储了state、mutation、action、getter相关数据。通过调用commit、dispatch修改state中的值。同时绑定数据,实现对数据的监听。
//通过Vue的响应式来达到对state数据的监听和getters达到计算属性效果
store._vm = new Vue({
data: {
$$state: state
},
computed
})
mutation不能使用异步请求
commit (_type, _payload, _options) {
// check object-style commit
const {
type,
payload,
options
} = unifyObjectStyle(_type, _payload, _options) //@doc 统一格式,支持对象风格
const mutation = { type, payload } //@doc mutation的参数
const entry = this._mutations[type]
if (!entry) {
if (process.env.NODE_ENV !== 'production') {
console.error(`[vuex] unknown mutation type: ${type}`)
}
return
}
this._withCommit(() => {
entry.forEach(function commitIterator (handler) {
handler(payload)
})
})
this._subscribers.forEach(sub => sub(mutation, this.state)) //@doc 订阅的插件执行
if (
process.env.NODE_ENV !== 'production' &&
options && options.silent
) {
console.warn(
`[vuex] mutation type: ${type}. Silent option has been removed. ` +
'Use the filter functionality in the vue-devtools'
)
}
}
因为_withCommit函数没有支持异步回调,如果mutation中执行异步操作,那么插件(_subscribers一般是使用插件的时候使用)中的数据可能不正确。而dispatch采用Promise,所以可以支持回调。
dispatch (_type, _payload) {
// check object-style dispatch
const {
type,
payload
} = unifyObjectStyle(_type, _payload)
const action = { type, payload }
const entry = this._actions[type]
if (!entry) {
if (process.env.NODE_ENV !== 'production') {
console.error(`[vuex] unknown action type: ${type}`)
}
return
}
try {
this._actionSubscribers
.filter(sub => sub.before)
.forEach(sub => sub.before(action, this.state))
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
console.warn(`[vuex] error in before action subscribers: `)
console.error(e)
}
}
//@doc 使用Promise
const result = entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
return result.then(res => {
try {
this._actionSubscribers
.filter(sub => sub.after)
.forEach(sub => sub.after(action, this.state))
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
console.warn(`[vuex] error in after action subscribers: `)
console.error(e)
}
}
return res
})
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。