Vuex
打包
{
name:'vuex',
...
main:'dist/vuex.common.js',
module:'dist/vuex.esm.js'
...
}
export default createEntries([
...
{input:'src/index.js',file:'dist/vuex.esm.js',format:'es',env:'development'},
...
{input:'src/index.cjs.js',file:'dist/vuex.common.js',format:'cjs',ebv:'development'}
])
vuex
import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespaceHelpers } from './helpers'
import createLogger from './plugins/logger'
export default{
Store,
install,
version:'__VERSION__',
mapState,
mapMutations,
mapGetters,
mapActions,
createNamespaceHelpers,
createLogger
}
Store
let Vue
class Store{
constructor(options = {}){
if(!Vue && typeof window !== 'undefined' && window.Vue){
install(window.Vue)
}
const { plugins = [], strict = false } = options
this._commiting = false
this._actions = Object.create(null)
this._actionSubscribers = []
this._mutations = Object.create(null)
this._wrappedGetters = Object.create(null)
this._modules = new ModuleCollection(options)
this._modulesNamespaceMap = Object.create(null)
this._subscribers = []
this._watcherVM = new Vue()
this._makeLocalGettersCache = Object.create(null)
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch(type,payload){
return dispatch.call(store,type,payload)
}
this.commit = function boundCommit(type,payload,options){
return commit.call(store,type,payload,options)
}
this.strict = strict
const state = this._modules.root.state
installModule(this,state,[],this._modules.root)
resetStoreVM(this,state)
plugins.forEach(plugin => plugin(this))
const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
if(useDevtools){
devtoolPlugin(this)
}
}
get state(){
return this._vm._data.$$state
}
set state(v){
if(__DEV__){
asset(false,`use store.replaceState() to explicit replace store state`)
}
}
commit(_type,_payload,_options){
const { type, payload, options} = unifyObjectStyle(_type,_payload,_options)
const mutation = { type, payload }
const entry = this._mutations[type]
if(!entry){
if(__DEV__){
console.error(`[vuex] unkonwn mutation type:${type}`)
}
return
}
this._withCommit(() => {
entry.forEach(function commitIterator(handler){
handler(payload)
})
})
this._subscribers.slice().forEach(sub => sub(mutation,this.state))
if(__DEV__ && options && options.slient){
console.warn(`[vuex] mutation type: ${type}. Slient option has been removed. use the filter funtionality in the vue-devtools`)
}
}
dispatch(_type,_payload){
const { type, payload }= unifyObjectStyle(_type,_payload)
const action = { type, payload }
const entry = this.actions[type]
if(!entry){
if(__DEV__){
console.error(`[vuex] unkonwn action type:${type}`)
}
return
}
try{
this._actionSubscribers.slice().filter(sub => sub.before).forEach(sub => sub.before(action,this.state))
}catch(e){
...
}
const result = entry.length > 1 ? Promise.all(entry.map(handler => handler(payload))) : entry[0].payload
return new Promise((resolve,reject) => {
result.then(res => {
try{
this._actionSubscribers.slice().filter(sub => sub.after).forEach(sub => sub.afetr(action,this.state))
}catch(e){
...
}
resolve(res)
})
},error => {
try{
this._actionSubscribers.slice().filter(sub => sub.error).forEach(sub=>sub.error(action,this.state,error))
}catch(e){
...
}
reject(error)
})
}
subscribe(fn,options){
return genericSubscribe(fn,this._subscribers,options)
}
subscribeAction(fn,options){
const subs = typeof fn === 'function' ? { before: fn} : fn
return genericSubscribe(fn,this._actionSubscribers,options)
}
watch(getter,cb,options){
if(__DEV__){
asset(typeof getter === 'function',`store.watch only accepts a function`)
}
return this._watcherVM.$watch(() => getter(this.state,this.getters),cb,options)
}
replaceState(state){
this._withCommit(() => {
this._vm._data.$$state = state
})
}
registerModule(path,rawModule,options = {}){
if(typeof path === 'string') path = [path]
if(__DEV__){
assert(Array.isArray(path),`module path must be a string or a Array`)
assert(path.length > 0,`cannot register the root module by using registerModule`)
}
this._modules.register(path,rawModule)
installModule(this,this.state,path,this._module.get(path),options.prevState)
resetStoreVM(this,this.state)
}
unregisterModule(path){
if(typeof path === 'string') path = [path]
if(__DEV__){
asset(Array.isArray(path),`module path must be a string or a array`)
}
this._modules.unregister(path)
this._withCommit(() => {
const parentState = getNestedState(this.state,path.slice(0,-1))
Vue.delete(parentState,path[path.length - 1])
})
resetStore(this)
}
hasModule(path){
if(typeof path === 'string') path = [path]
if(__DEV__){
asset(Array.isArray(path),`module path must be a string or a array`)
}
return this._modules.isRegistered(path)
}
hotUpdate(newOptions){
this._modules.update(newOptions)
resetStore(this)
}
_withCommit(fn){
const commiting = this._committing
this._committing = true
fn()
this._committing = committing
}
}