VuexÊÇÒ»¸öרΪVue·þÎñ£¬ÓÃÓÚ¹ÜÀíÒ³ÃæÊý¾Ý״̬¡¢ÌṩͳһÊý¾Ý²Ù×÷µÄÉú̬ϵͳ¡£Ëü¼¯ÖÐÓÚMVCģʽÖеÄModel²ã£¬¹æ¶¨ËùÓеÄÊý¾Ý²Ù×÷±ØÐëͨ¹ý
action - mutation - state change µÄÁ÷³ÌÀ´½øÐУ¬ÔÙ½áºÏVueµÄÊý¾ÝÊÓͼ˫Ïò°ó¶¨ÌØÐÔÀ´ÊµÏÖÒ³ÃæµÄչʾ¸üС£Í³Ò»µÄÒ³Ãæ×´Ì¬¹ÜÀíÒÔ¼°²Ù×÷´¦Àí£¬¿ÉÒÔÈø´ÔÓµÄ×é¼þ½»»¥±äµÃ¼òµ¥ÇåÎú£¬Í¬Ê±¿ÉÔÚµ÷ÊÔģʽϽøÐÐʱ¹â»ú°ãµÄµ¹ÍËǰ½ø²Ù×÷£¬²é¿´Êý¾Ý¸Ä±ä¹ý³Ì£¬Ê¹code
debug¸ü¼Ó·½±ã¡£
×î½üÔÚ¿ª·¢µÄÏîÄ¿ÖÐÓõ½ÁËVuexÀ´¹ÜÀíÕûÌåÒ³Ãæ×´Ì¬£¬Óöµ½Á˺ܶàÎÊÌâ¡£¾ö¶¨Ñо¿ÏÂÔ´Â룬ÔÚ´ðÒɽâ»óÖ®Í⣬ÄÜÉîÈëѧϰÆäʵÏÖÔÀí¡£
ÏȽ«ÎÊÌâÅ׳öÀ´£¬Ê¹Ñ§Ï°ºÍÑо¿¸üÓÐÕë¶ÔÐÔ£º
ʹÓÃVuexÖ»ÐèÖ´ÐÐ Vue.use(Vuex)£¬²¢ÔÚVueµÄÅäÖÃÖд«ÈëÒ»¸östore¶ÔÏóµÄʾÀý£¬storeÊÇÈçºÎʵÏÖ×¢ÈëµÄ£¿
stateÄÚ²¿ÊÇÈçºÎʵÏÖÖ§³ÖÄ£¿éÅäÖúÍÄ£¿éǶÌ׵ģ¿
ÔÚÖ´ÐÐdispatch´¥·¢action£¨commitͬÀí£©µÄʱºò£¬Ö»Ðè´«È루type, payload£©£¬actionÖ´Ðк¯ÊýÖеÚÒ»¸ö²ÎÊýstore´ÓÄÄÀï»ñÈ¡µÄ£¿
ÈçºÎÇø·ÖstateÊÇÍⲿֱ½ÓÐ޸쬻¹ÊÇͨ¹ýmutation·½·¨Ð޸ĵģ¿
µ÷ÊÔʱµÄ¡°Ê±¿Õ´©Ëó¡±¹¦ÄÜÊÇÈçºÎʵÏֵģ¿
×¢£º±¾ÎĶÔÓÐVuexÓÐʵ¼ÊʹÓþÑéµÄͬѧ°ïÖú¸ü´ó£¬ÄܸüÇåÎúÀí½âVuexµÄ¹¤×÷Á÷³ÌºÍÔÀí£¬Ê¹ÓÃÆðÀ´¸üµÃÐÄÓ¦ÊÖ¡£³õ´Î½Ó´¥µÄͬѧ£¬¿ÉÒÔÏȲο¼Vuex¹Ù·½Îĵµ½øÐлù´¡¸ÅÄîµÄѧϰ¡£
Ò»¡¢¿ò¼ÜºËÐÄÁ÷³Ì
½øÐÐÔ´Âë·ÖÎö֮ǰ£¬ÏÈÁ˽âһϹٷ½ÎĵµÖÐÌṩµÄºËÐÄ˼Ïëͼ£¬ËüÒ²´ú±í×ÅÕû¸öVuex¿ò¼ÜµÄÔËÐÐÁ÷³Ì¡£

Èçͼʾ£¬VuexΪVue Components½¨Á¢ÆðÁËÒ»¸öÍêÕûµÄÉú̬Ȧ£¬°üÀ¨¿ª·¢ÖеÄAPIµ÷ÓÃÒ»»·¡£Î§ÈÆÕâ¸öÉú̬Ȧ£¬¼òÒª½éÉÜһϸ÷Ä£¿éÔÚºËÐÄÁ÷³ÌÖеÄÖ÷Òª¹¦ÄÜ£º
Vue Components£ºVue×é¼þ¡£HTMLÒ³ÃæÉÏ£¬¸ºÔð½ÓÊÕÓû§²Ù×÷µÈ½»»¥ÐÐΪ£¬Ö´ÐÐdispatch·½·¨´¥·¢¶ÔÓ¦action½øÐлØÓ¦¡£
dispatch£º²Ù×÷ÐÐΪ´¥·¢·½·¨£¬ÊÇΨһÄÜÖ´ÐÐactionµÄ·½·¨¡£
actions£º²Ù×÷ÐÐΪ´¦ÀíÄ£¿é¡£¸ºÔð´¦ÀíVue Components½ÓÊÕµ½µÄËùÓн»»¥ÐÐΪ¡£°üº¬Í¬²½/Òì²½²Ù×÷£¬Ö§³Ö¶à¸öͬÃû·½·¨£¬°´ÕÕ×¢²áµÄ˳ÐòÒÀ´Î´¥·¢¡£Ïòºǫ́APIÇëÇóµÄ²Ù×÷¾ÍÔÚÕâ¸öÄ£¿éÖнøÐУ¬°üÀ¨´¥·¢ÆäËûactionÒÔ¼°Ìá½»mutationµÄ²Ù×÷¡£¸ÃÄ£¿éÌṩÁËPromiseµÄ·â×°£¬ÒÔÖ§³ÖactionµÄÁ´Ê½´¥·¢¡£
commit£º×´Ì¬¸Ä±äÌá½»²Ù×÷·½·¨¡£¶Ômutation½øÐÐÌá½»£¬ÊÇΨһÄÜÖ´ÐÐmutationµÄ·½·¨¡£
mutations£º×´Ì¬¸Ä±ä²Ù×÷·½·¨¡£ÊÇVuexÐÞ¸ÄstateµÄÎ¨Ò»ÍÆ¼ö·½·¨£¬ÆäËûÐ޸ķ½Ê½ÔÚÑϸñģʽϽ«»á±¨´í¡£¸Ã·½·¨Ö»ÄܽøÐÐͬ²½²Ù×÷£¬ÇÒ·½·¨ÃûÖ»ÄÜÈ«¾ÖΨһ¡£²Ù×÷Ö®ÖлáÓÐһЩhook±©Â¶³öÀ´£¬ÒÔ½øÐÐstateµÄ¼à¿ØµÈ¡£
state£ºÒ³Ãæ×´Ì¬¹ÜÀíÈÝÆ÷¶ÔÏó¡£¼¯Öд洢Vue componentsÖÐdata¶ÔÏóµÄÁãÉ¢Êý¾Ý£¬È«¾ÖΨһ£¬ÒÔ½øÐÐͳһµÄ״̬¹ÜÀí¡£Ò³ÃæÏÔʾËùÐèµÄÊý¾Ý´Ó¸Ã¶ÔÏóÖнøÐжÁÈ¡£¬ÀûÓÃVueµÄϸÁ£¶ÈÊý¾ÝÏìÓ¦»úÖÆÀ´½øÐиßЧµÄ״̬¸üС£
getters£ºstate¶ÔÏó¶ÁÈ¡·½·¨¡£Í¼ÖÐûÓе¥¶ÀÁгö¸ÃÄ£¿é£¬Ó¦¸Ã±»°üº¬ÔÚÁËrenderÖУ¬Vue
Componentsͨ¹ý¸Ã·½·¨¶Áȡȫ¾Östate¶ÔÏó¡£
Vue×é¼þ½ÓÊÕ½»»¥ÐÐΪ£¬µ÷ÓÃdispatch·½·¨´¥·¢actionÏà¹Ø´¦Àí£¬ÈôÒ³Ãæ×´Ì¬ÐèÒª¸Ä±ä£¬Ôòµ÷ÓÃcommit·½·¨Ìá½»mutationÐÞ¸Ästate£¬Í¨¹ýgetters»ñÈ¡µ½stateÐÂÖµ£¬ÖØÐÂäÖȾVue
Components£¬½çÃæËæÖ®¸üС£
¶þ¡¢Ä¿Â¼½á¹¹½éÉÜ
´ò¿ªVuexÏîÄ¿£¬¿´ÏÂÔ´ÂëĿ¼½á¹¹¡£

VuexÌṩÁ˷dz£Ç¿´óµÄ״̬¹ÜÀí¹¦ÄÜ£¬Ô´Âë´úÂëÁ¿È´²»¶à£¬Ä¿Â¼½á¹¹»®·ÖÒ²ºÜÇåÎú¡£ÏÈ´óÌå½éÉÜϸ÷¸öĿ¼ÎļþµÄ¹¦ÄÜ£º
module£ºÌṩmodule¶ÔÏóÓëmodule¶ÔÏóÊ÷µÄ´´½¨¹¦ÄÜ£»
plugins£ºÌṩ¿ª·¢¸¨Öú²å¼þ£¬È硰ʱ¹â´©Ëó¡±¹¦ÄÜ£¬stateÐ޸ĵÄÈÕÖ¾¼Ç¼¹¦Äܵȣ»
helpers.js£ºÌṩaction¡¢mutationsÒÔ¼°gettersµÄ²éÕÒAPI£»
index.js£ºÊÇÔ´ÂëÖ÷Èë¿ÚÎļþ£¬ÌṩstoreµÄ¸÷module¹¹½¨°²×°£»
mixin.js£ºÌṩÁËstoreÔÚVueʵÀýÉϵÄ×°ÔØ×¢È룻
util.js£ºÌṩÁ˹¤¾ß·½·¨Èçfind¡¢deepCopy¡¢forEachValueÒÔ¼°assertµÈ·½·¨¡£
Èý¡¢³õʼ»¯×°ÔØÓë×¢Èë
Á˽â´ó¸ÅµÄĿ¼¼°¶ÔÓ¦¹¦Äܺó£¬ÏÂÃæ¿ªÊ¼½øÐÐÔ´Âë·ÖÎö¡£index.jsÖаüº¬ÁËËùÓеĺËÐÄ´úÂ룬´Ó¸ÃÎļþÈëÊÖ½øÐзÖÎö¡£
3.1 ×°ÔØÊµÀý
ÏÈ¿´¸ö¼òµ¥µÄÀý×Ó£º
/**
* store.jsÎļþ
* ´´½¨store¶ÔÏó£¬ÅäÖÃstate¡¢action¡¢mutationÒÔ¼°getter
*
**/
import Vue from 'vue'
import Vuex from 'vuex'
// install Vuex¿ò¼Ü
Vue.use(Vuex)
// ´´½¨²¢µ¼³östore¶ÔÏó¡£ÎªÁË·½±ã£¬²»ÅäÖÃÈκβÎÊý
export default new Vuex.Store() |
store.jsÎļþÖУ¬¼ÓÔØVuex¿ò¼Ü£¬´´½¨²¢µ¼³öÒ»¸ö¿ÕÅäÖõÄstore¶ÔÏóʵÀý¡£
/**
* vue-index.jsÎļþ
*
*
**/
import Vue from 'vue'
import App from './../pages/app.vue'
import store from './store.js'
new Vue({
el: '#root',
router,
store,
render: h => h(App)
}) |
È»ºóÔÚindex.jsÖУ¬Õý³£³õʼ»¯Ò»¸öÒ³Ãæ¸ù¼¶±ðµÄVue×é¼þ£¬´«ÈëÕâ¸ö×Ô¶¨ÒåµÄstore¶ÔÏó¡£
ÈçÎÊÌâ1ËùÊö£¬ÒÔÉÏʵÀý³ýÁËVueµÄ³õʼ»¯´úÂ룬ֻÊǶàÁËÒ»¸östore¶ÔÏóµÄ´«Èë¡£Ò»Æð¿´ÏÂÔ´ÂëÖеÄʵÏÖ·½Ê½¡£
3.2 ×°ÔØ·ÖÎö
index.jsÎļþ´úÂëÖ´ÐпªÍ·£¬¶¨Òå¾Ö²¿ Vue ±äÁ¿£¬ÓÃÓÚÅжÏÊÇ·ñÒÑ¾×°ÔØºÍ¼õÉÙÈ«¾Ö×÷ÓÃÓò²éÕÒ¡£
È»ºóÅжÏÈô´¦ÓÚä¯ÀÀÆ÷»·¾³ÏÂÇÒ¼ÓÔØ¹ýVue£¬ÔòÖ´ÐÐinstall·½·¨¡£
// auto install
in dist mode
if (typeof window !== 'undefined' && window.Vue)
{
install(window.Vue)
} |
install·½·¨½«Vuex×°ÔØµ½Vue¶ÔÏóÉÏ£¬Vue.use(Vuex) Ò²ÊÇͨ¹ýËüÖ´ÐУ¬ÏÈ¿´ÏÂVue.use·½·¨ÊµÏÖ£º
function (plugin: Function
| Object) {
/* istanbul ignore if */
if (plugin.installed) {
return
}
// additional parameters
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
// ʵ¼ÊÖ´Ðвå¼þµÄinstall·½·¨
plugin.install.apply(plugin, args)
} else {
plugin.apply(null, args)
}
plugin.installed = true
return this
} |
ÈôÊÇÊ״μÓÔØ£¬½«¾Ö²¿Vue±äÁ¿¸³ÖµÎªÈ«¾ÖµÄVue¶ÔÏ󣬲¢Ö´ÐÐapplyMixin·½·¨£¬installʵÏÖÈçÏ£º
function install (_Vue) {
if (Vue) {
console.error(
'[vuex] already installed. Vue.use(Vuex) should
be called only once.'
)
return
}
Vue = _Vue
applyMixin(Vue)
} |
À´¿´ÏÂapplyMixin·½·¨ÄÚ²¿´úÂë¡£Èç¹ûÊÇ2.x.xÒÔÉϰ汾£¬¿ÉÒÔʹÓà hook µÄÐÎʽ½øÐÐ×¢È룬»òʹÓ÷â×°²¢Ìæ»»Vue¶ÔÏóÔÐ͵Ä_init·½·¨£¬ÊµÏÖ×¢Èë¡£
export default function (Vue)
{
const version = Number(Vue.version.split('.')[0])
if (version >= 2) {
const usesInit = Vue.config._lifecycleHooks.indexOf('init')
> -1
Vue.mixin(usesInit ? { init: vuexInit } : {
beforeCreate: vuexInit })
} else {
// override init and inject vuex init procedure
// for 1.x backwards compatibility.
const _init = Vue.prototype._init
Vue.prototype._init = function (options = {})
{
options.init = options.init
? [vuexInit].concat(options.init)
: vuexInit
_init.call(this, options)
}
} |
¾ßÌåʵÏÖ£º½«³õʼ»¯Vue¸ù×é¼þʱ´«ÈëµÄstoreÉèÖõ½this¶ÔÏóµÄ$storeÊôÐÔÉÏ£¬×Ó×é¼þ´ÓÆä¸¸×é¼þÒýÓÃ$storeÊôÐÔ£¬²ã²ãǶÌ×½øÐÐÉèÖá£ÔÚÈÎÒâ×é¼þÖÐÖ´ÐÐ
this.$store ¶¼ÄÜÕÒµ½×°ÔصÄÄǸöstore¶ÔÏó£¬vuexInit·½·¨ÊµÏÖÈçÏ£º
function vuexInit () {
const options = this.$options
// store injection
if (options.store) {
this.$store = options.store
} else if (options.parent && options.parent.$store)
{
this.$store = options.parent.$store
}
} |
¿´¸öͼÀýÀí½âÏÂstoreµÄ´«µÝ¡£
Ò³ÃæVue½á¹¹Í¼£º 
¶ÔÓ¦storeÁ÷Ïò£º 
ËÄ¡¢store¶ÔÏó¹¹Ôì
ÉÏÃæ¶ÔVuex¿ò¼ÜµÄ×°ÔØÒÔ¼°×¢Èë×Ô¶¨Òåstore¶ÔÏó½øÐзÖÎö£¬½â¾öÁËÎÊÌâ1¡£½ÓÏÂÀ´Ïêϸ·ÖÎöstore¶ÔÏóµÄÄÚ²¿¹¦Äܺ;ßÌåʵÏÖ£¬À´½â´ð
Ϊʲôactions¡¢getters¡¢mutationsÖÐÄÜ´Óarguments[0]ÖÐÄõ½storeµÄÏà¹ØÊý¾Ý?
µÈÎÊÌâ¡£
store¶ÔÏóʵÏÖÂß¼±È½Ï¸´ÔÓ£¬ÏÈ¿´Ï¹¹Ôì·½·¨µÄÕûÌåÂß¼Á÷³ÌÀ´°ïÖúºóÃæµÄÀí½â£º

4.1 »·¾³ÅжÏ
¿ªÊ¼·ÖÎöstoreµÄ¹¹Ô캯Êý£¬·ÖС½ÚÖðº¯ÊýÖðÐеķÖÎöÆä¹¦ÄÜ¡£
constructor (options = {})
{
assert (Vue, `must call Vue.use(Vuex) before creating
a store instance.`)
assert (typeof Promise !== 'undefined', `vuex
requires a Promise polyfill in this browser.`) |
ÔÚstore¹¹Ô캯ÊýÖÐÖ´Ðл·¾³Åжϣ¬ÒÔ϶¼ÊÇVuex¹¤×÷µÄ±ØÒªÌõ¼þ£º
ÒѾִÐа²×°º¯Êý½øÐÐ×°ÔØ£»
Ö§³ÖPromiseÓï·¨¡£
assertº¯ÊýÊÇÒ»¸ö¼òµ¥µÄ¶ÏÑÔº¯ÊýµÄʵÏÖ£¬Ò»ÐдúÂë¼´¿ÉʵÏÖ¡£
function assert (condition,
msg) {
if (!condition) throw new Error(`[vuex] ${msg}`)
} |
4.2 Êý¾Ý³õʼ»¯¡¢moduleÊ÷¹¹Ôì
»·¾³ÅжϺ󣬸ù¾Ýnew¹¹Ôì´«ÈëµÄoptions»òĬÈÏÖµ£¬³õʼ»¯ÄÚ²¿Êý¾Ý¡£
const {
state = {},
plugins = [],
strict = false
} = options
// store internal state
this._committing = false // ÊÇ·ñÔÚ½øÐÐÌύ״̬±êʶ
this._actions = Object.create(null) // acitons²Ù×÷¶ÔÏó
this._mutations = Object.create(null) // mutations²Ù×÷¶ÔÏó
this._wrappedGetters = Object.create(null) //
·â×°ºóµÄgetters¼¯ºÏ¶ÔÏó
this._modules = new ModuleCollection(options)
// VuexÖ§³Östore·ÖÄ£¿é´«È룬´æ´¢·ÖÎöºóµÄmodules
this._modulesNamespaceMap = Object.create(null)
// Ä£¿éÃüÃû¿Õ¼ämap
this._subscribers = [] // ¶©Ôĺ¯Êý¼¯ºÏ£¬VuexÌṩÁËsubscribe¹¦ÄÜ
this._watcherVM = new Vue() // Vue×é¼þÓÃÓÚwatch¼àÊӱ仯 |
µ÷Óà new Vuex.store(options) ʱ´«ÈëµÄoptions¶ÔÏó£¬ÓÃÓÚ¹¹ÔìModuleCollectionÀ࣬ÏÂÃæ¿´¿´Æä¹¦ÄÜ¡£
constructor (rawRootModule)
{
// register root module (Vuex.Store options)
this.root = new Module(rawRootModule, false)
// register all nested modules
if (rawRootModule.modules) {
forEachValue(rawRootModule.modules, (rawModule,
key) => {
this.register([key], rawModule, false)
})
} |
ModuleCollectionÖ÷Òª½«´«ÈëµÄoptions¶ÔÏóÕû¸ö¹¹ÔìΪһ¸ömodule¶ÔÏ󣬲¢Ñ»·µ÷ÓÃ
this.register([key], rawModule, false) ΪÆäÖеÄmodulesÊôÐÔ½øÐÐÄ£¿é×¢²á£¬Ê¹Æä¶¼³ÉΪmodule¶ÔÏó£¬×îºóoptions¶ÔÏó±»¹¹Ôì³ÉÒ»¸öÍêÕûµÄ×é¼þÊ÷¡£ModuleCollectionÀ໹ÌṩÁËmodulesµÄ¸üÌæ¹¦ÄÜ£¬ÏêϸʵÏÖ¿ÉÒԲ鿴ԴÎļþmodule-collection.js¡£
4.3 dispatchÓëcommitÉèÖÃ
¼ÌÐø»Øµ½storeµÄ¹¹Ô캯Êý´úÂë¡£
// bind commit and dispatch
to self
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)
} |
·â×°Ìæ»»ÔÐÍÖеÄdispatchºÍcommit·½·¨£¬½«thisÖ¸Ïòµ±Ç°store¶ÔÏó¡£dispatchºÍcommit·½·¨¾ßÌåʵÏÖÈçÏ£º
dispatch (_type, _payload)
{
// check object-style dispatch
const {
type,
payload
} = unifyObjectStyle(_type, _payload) // ÅäÖòÎÊý´¦Àí
// µ±Ç°typeÏÂËùÓÐaction´¦Àíº¯Êý¼¯ºÏ
const entry = this._actions[type]
if (!entry) {
console.error(`[vuex] unknown action type: ${type}`)
return
}
return entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
} |
Ç°ÃæÌáµ½£¬dispatchµÄ¹¦ÄÜÊÇ´¥·¢²¢´«µÝһЩ²ÎÊý£¨payload£©¸ø¶ÔÓ¦typeµÄaction¡£ÒòΪÆäÖ§³Ö2ÖÖµ÷Ó÷½·¨£¬ËùÒÔÔÚdispatchÖУ¬ÏȽøÐвÎÊýµÄÊÊÅä´¦Àí£¬È»ºóÅжÏaction
typeÊÇ·ñ´æÔÚ£¬Èô´æÔÚ¾ÍÖð¸öÖ´ÐУ¨×¢£ºÉÏÃæ´úÂëÖеÄthis._actions[type] ÒÔ¼° ÏÂÃæµÄ
this._mutations[type] ¾ùÊÇ´¦Àí¹ýµÄº¯Êý¼¯ºÏ£¬¾ßÌåÄÚÈÝÁôµ½ºóÃæ½øÐзÖÎö£©¡£
commit·½·¨ºÍdispatchÏà±ÈËäÈ»¶¼ÊÇ´¥·¢type£¬µ«ÊǶÔÓ¦µÄ´¦ÀíÈ´Ïà¶Ô¸´ÔÓ£¬´úÂëÈçÏ¡£
commit (_type, _payload,
_options) {
// check object-style commit
const {
type,
payload,
options
} = unifyObjectStyle(_type, _payload, _options)
const mutation = { type, payload }
const entry = this._mutations[type]
if (!entry) {
console.error(`[vuex] unknown mutation type:
${type}`)
return
}
// רÓÃÐÞ¸Ästate·½·¨£¬ÆäËûÐÞ¸Ästate·½·¨¾ùÊÇ·Ç·¨ÐÞ¸Ä
this._withCommit(() => {
entry.forEach(function commitIterator (handler)
{
handler(payload)
})
})
// ¶©ÔÄÕߺ¯Êý±éÀúÖ´ÐУ¬´«È뵱ǰµÄmutation¶ÔÏóºÍµ±Ç°µÄstate
this._subscribers.forEach(sub => sub(mutation,
this.state))
if (options && options.silent) {
console.warn(
`[vuex] mutation type: ${type}. Silent option
has been removed. ` +
'Use the filter functionality in the vue-devtools'
)
}
} |
¸Ã·½·¨Í¬ÑùÖ§³Ö2ÖÖµ÷Ó÷½·¨¡£ÏȽøÐвÎÊýÊÊÅ䣬Åжϴ¥·¢mutation type£¬ÀûÓÃ_withCommit·½·¨Ö´Ðб¾´ÎÅúÁ¿´¥·¢mutation´¦Àíº¯Êý£¬²¢´«Èëpayload²ÎÊý¡£Ö´ÐÐÍê³Éºó£¬Í¨ÖªËùÓÐ_subscribers£¨¶©Ôĺ¯Êý£©±¾´Î²Ù×÷µÄmutation¶ÔÏóÒÔ¼°µ±Ç°µÄstate״̬£¬Èç¹û´«ÈëÁËÒÑ¾ÒÆ³ýµÄsilentÑ¡ÏîÔò½øÐÐÌáʾ¾¯¸æ¡£
4.4 stateÐ޸ķ½·¨
_withCommitÊÇÒ»¸ö´úÀí·½·¨£¬ËùÓд¥·¢mutationµÄ½øÐÐstateÐ޸ĵIJÙ×÷¶¼¾¹ýËü£¬ÓÉ´ËÀ´Í³Ò»¹ÜÀí¼à¿Østate״̬µÄÐ޸ġ£ÊµÏÖ´úÂëÈçÏ¡£
_withCommit (fn) {
// ±£´æÖ®Ç°µÄÌύ״̬
const committing = this._committing
// ½øÐб¾´ÎÌá½»£¬Èô²»ÉèÖÃΪtrue£¬Ö±½ÓÐÞ¸Ästate£¬strictģʽÏ£¬Vuex½«»á²úÉú·Ç·¨ÐÞ¸ÄstateµÄ¾¯¸æ
this._committing = true
// Ö´ÐÐstateµÄÐ޸IJÙ×÷
fn()
// ÐÞ¸ÄÍê³É£¬»¹Ô±¾´ÎÐÞ¸Ä֮ǰµÄ״̬
this._committing = committing
} |
»º´æÖ´ÐÐʱµÄcommitting״̬½«µ±Ç°×´Ì¬ÉèÖÃΪtrueºó½øÐб¾´ÎÌá½»²Ù×÷£¬´ý²Ù×÷Íê±Ïºó£¬½«committing״̬»¹ÔΪ֮ǰµÄ״̬¡£
4.5 module°²×°
°ó¶¨dispatchºÍcommit·½·¨Ö®ºó£¬½øÐÐÑϸñģʽµÄÉèÖã¬ÒÔ¼°Ä£¿éµÄ°²×°£¨installModule£©¡£ÓÉÓÚÕ¼ÓÃ×ÊÔ´½Ï¶àÓ°ÏìÒ³ÃæÐÔÄÜ£¬Ñϸñģʽ½¨ÒéÖ»ÔÚ¿ª·¢Ä£Ê½¿ªÆô£¬ÉÏÏߺóÐèÒª¹Ø±Õ¡£
// strict mode
this.strict = strict
// init root module.
// this also recursively registers all sub-modules
// and collects all module getters inside this._wrappedGetters
installModule(this, state, [], this._modules.root) |
4.5.1 ³õʼ»¯rootState
ÉÏÊö´úÂëµÄ±¸×¢ÖУ¬Ìáµ½installModule·½·¨³õʼ»¯×é¼þÊ÷¸ù×é¼þ¡¢×¢²áËùÓÐ×Ó×é¼þ£¬²¢½«ÆäÖÐËùÓеÄgetters´æ´¢µ½this._wrappedGettersÊôÐÔÖУ¬ÈÃÎÒÃÇ¿´¿´ÆäÖеĴúÂëʵÏÖ¡£
function installModule (store,
rootState, path, module, hot) {
const isRoot = !path.length
const namespace = store._modules.getNamespace(path)
// register in namespace map
if (namespace) {
store._modulesNamespaceMap[namespace] = module
}
// ·Ç¸ù×é¼þÉèÖà state ·½·¨
if (!isRoot && !hot) {
const parentState = getNestedState(rootState,
path.slice(0, -1))
const moduleName = path[path.length - 1]
store._withCommit(() => {
Vue.set(parentState, moduleName, module.state)
})
}
¡¤¡¤¡¤¡¤¡¤¡¤ |
ÅжÏÊÇ·ñÊǸùĿ¼£¬ÒÔ¼°ÊÇ·ñÉèÖÃÁËÃüÃû¿Õ¼ä£¬Èô´æÔÚÔòÔÚnamespaceÖнøÐÐmoduleµÄ´æ´¢£¬ÔÚ²»ÊǸù×é¼þÇÒ²»ÊÇ
hot Ìõ¼þµÄÇé¿öÏ£¬Í¨¹ýgetNestedState·½·¨Äõ½¸Ãmodule¸¸¼¶µÄstate£¬Äõ½ÆäËùÔÚµÄ
moduleName £¬µ÷Óà Vue.set(parentState, moduleName, module.state)
·½·¨½«ÆästateÉèÖõ½¸¸¼¶state¶ÔÏóµÄmoduleNameÊôÐÔÖУ¬ÓÉ´ËʵÏÖ¸ÃÄ£¿éµÄstate×¢²á£¨Ê×´ÎÖ´ÐÐÕâÀÒòΪÊǸùĿ¼ע²á£¬ËùÒÔ²¢²»»áÖ´ÐиÃÌõ¼þÖеķ½·¨£©¡£getNestedState·½·¨´úÂëºÜ¼òµ¥£¬·ÖÎöpathÄõ½state£¬ÈçÏ¡£
function getNestedState (state,
path) {
return path.length
? path.reduce((state, key) => state[key], state)
: state
} |
4.5.2 moduleÉÏÏÂÎÄ»·¾³ÉèÖÃ
const local = module.context
= makeLocalContext(store, namespace, path) |
ÃüÃû¿Õ¼äºÍ¸ùĿ¼Ìõ¼þÅжÏÍê±Ïºó£¬½ÓÏÂÀ´¶¨Òålocal±äÁ¿ºÍmodule.contextµÄÖµ£¬Ö´ÐÐmakeLocalContext·½·¨£¬Îª¸ÃmoduleÉèÖþֲ¿µÄ
dispatch¡¢commit·½·¨ÒÔ¼°gettersºÍstate£¨ÓÉÓÚnamespaceµÄ´æÔÚÐèÒª×ö¼æÈÝ´¦Àí£©¡£
4.5.3 mutations¡¢actionsÒÔ¼°getters×¢²á
¶¨Òålocal»·¾³ºó£¬Ñ»·×¢²áÎÒÃÇÔÚoptionsÖÐÅäÖõÄactionÒÔ¼°mutationµÈ¡£Öð¸ö·ÖÎö¸÷×¢²áº¯Êý֮ǰ£¬ÏÈ¿´ÏÂÄ£¿é¼äµÄÂß¼¹ØÏµÁ÷³Ìͼ£º

ÏÂÃæ·ÖÎö´úÂëÂß¼£º
// ×¢²á¶ÔӦģ¿éµÄmutation£¬¹©stateÐÞ¸ÄʹÓÃ
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation,
local)
})
// ×¢²á¶ÔӦģ¿éµÄaction£¬¹©Êý¾Ý²Ù×÷¡¢Ìá½»mutationµÈÒì²½²Ù×÷ʹÓÃ
module.forEachAction((action, key) => {
const namespacedType = namespace + key
registerAction(store, namespacedType, action,
local)
})
// ×¢²á¶ÔӦģ¿éµÄgetters£¬¹©state¶ÁȡʹÓÃ
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter,
local)
}) |
registerMutation·½·¨ÖУ¬»ñÈ¡storeÖеĶÔÓ¦mutation typeµÄ´¦Àíº¯Êý¼¯ºÏ£¬½«ÐµĴ¦Àíº¯Êýpush½øÈ¥¡£ÕâÀォÎÒÃÇÉèÖÃÔÚmutations
typeÉ϶ÔÓ¦µÄ handler ½øÐÐÁË·â×°£¬¸øÔº¯Êý´«ÈëÁËstate¡£ÔÚÖ´ÐÐ commit('xxx',
payload) µÄʱºò£¬typeΪ xxx µÄmutationµÄËùÓÐhandler¶¼»á½ÓÊÕµ½stateÒÔ¼°payload£¬Õâ¾ÍÊÇÔÚhandlerÀïÃæÄõ½stateµÄÔÒò¡£
function registerMutation
(store, type, handler, local) {
// È¡³ö¶ÔÓ¦typeµÄmutations-handler¼¯ºÏ
const entry = store._mutations[type] || (store._mutations[type]
= [])
// commitʵ¼Êµ÷ÓõIJ»ÊÇÎÒÃÇ´«ÈëµÄhandler£¬¶øÊǾ¹ý·â×°µÄ
entry.push(function wrappedMutationHandler (payload)
{
// µ÷ÓÃhandler²¢½«state´«Èë
handler(local.state, payload)
})
} |
actionºÍgetterµÄ×¢²áÒ²ÊÇͬÀíµÄ£¬¿´Ò»Ï´úÂ루ע£ºÇ°ÃæÌáµ½µÄ this.actions ÒÔ¼°
this.mutationsÔÚ´Ë´¦½øÐÐÉèÖã©¡£
function registerAction (store,
type, handler, local) {
// È¡³ö¶ÔÓ¦typeµÄactions-handler¼¯ºÏ
const entry = store._actions[type] || (store._actions[type]
= [])
// ´æ´¢Ðµķâ×°¹ýµÄaction-handler
entry.push(function wrappedActionHandler (payload,
cb) {
// ´«Èë state µÈ¶ÔÏó¹©ÎÒÃÇÔaction-handlerʹÓÃ
let res = handler({
dispatch: local.dispatch,
commit: local.commit,
getters: local.getters,
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload, cb)
// actionÐèÒªÖ§³Öpromise½øÐÐÁ´Ê½µ÷Óã¬ÕâÀï½øÐмæÈÝ´¦Àí
if (!isPromise(res)) {
res = Promise.resolve(res)
}
if (store._devtoolHook) {
return res.catch(err => {
store._devtoolHook.emit('vuex:error', err)
throw err
})
} else {
return res
}
})
}
function registerGetter (store, type, rawGetter,
local) {
// gettersÖ»ÔÊÐí´æÔÚÒ»¸ö´¦Àíº¯Êý£¬ÈôÖØ¸´ÐèÒª±¨´í
if (store._wrappedGetters[type]) {
console.error(`[vuex] duplicate getter key:
${type}`)
return
}
// ´æ´¢·â×°¹ýµÄgetters´¦Àíº¯Êý
store._wrappedGetters[type] = function wrappedGetter
(store) {
// ΪÔgetters´«Èë¶ÔӦ״̬
return rawGetter(
local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
)
}
} |
action handler±Èmutation handlerÒÔ¼°getter wrapper¶àÄõ½dispatchºÍcommit²Ù×÷·½·¨£¬Òò´Ëaction¿ÉÒÔ½øÐÐdispatch
actionºÍcommit mutation²Ù×÷¡£
4.5.4 ×Ómodule°²×°
×¢²áÍêÁ˸ù×é¼þµÄactions¡¢mutationsÒÔ¼°gettersºó£¬µÝ¹éµ÷ÓÃ×ÔÉí£¬Îª×Ó×é¼þ×¢²áÆästate£¬actions¡¢mutationsÒÔ¼°gettersµÈ¡£
module.forEachChild((child,
key) => {
installModule(store, rootState, path.concat(key),
child, hot)
}) |
4.5.5 ʵÀý½áºÏ
Ç°Ãæ½éÉÜÁËdispatchºÍcommit·½·¨ÒÔ¼°actionsµÈµÄʵÏÖ£¬ÏÂÃæ½áºÏÒ»¸ö¹Ù·½µÄ¹ºÎﳵʵÀýÖеIJ¿·Ö´úÂëÀ´¼ÓÉîÀí½â¡£
VuexÅäÖôúÂ룺
/
* store-index.js storeÅäÖÃÎļþ
*
/
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import cart from './modules/cart'
import products from './modules/products'
import createLogger from '../../../src/plugins/logger'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
actions,
getters,
modules: {
cart,
products
},
strict: debug,
plugins: debug ? [createLogger()] : []
}) |
Vuex×é¼þmoduleÖи÷Ä£¿éstateÅäÖôúÂ벿·Ö£º
/**
* cart.js
*
**/
const state = {
added: [],
checkoutStatus: null
}
/**
* products.js
*
**/
const state = {
all: []
} |
¼ÓÔØÉÏÊöÅäÖúó£¬Ò³Ãæstate½á¹¹ÈçÏÂͼ£º
cart_state
stateÖеÄÊôÐÔÅäÖö¼Êǰ´ÕÕoptionÅäÖÃÖÐmodule pathµÄ¹æÔòÀ´½øÐеģ¬ÏÂÃæ¿´actionµÄ²Ù×÷ʵÀý¡£
Vuecart×é¼þ´úÂ벿·Ö£º
/**
* Cart.vue Ê¡ÂÔtemplate´úÂ룬ֻ¿´script²¿·Ö
*
**/
export default {
methods: {
// ¹ºÎï³µÖеĹºÂò°´Å¥£¬µã»÷ºó»á´¥·¢½áËã¡£Ô´ÂëÖлáµ÷Óà dispatch·½·¨
checkout (products) {
this.$store.dispatch('checkout', products)
}
}
}
Vuexca |
Vuexcart.js×é¼þactionÅäÖôúÂ벿·Ö£º
const actions = {
checkout ({ commit, state }, products) {
const savedCartItems = [...state.added] // ´æ´¢Ìí¼Óµ½¹ºÎï³µµÄÉÌÆ·
commit(types.CHECKOUT_REQUEST) // ÉèÖÃÌá½»½áËã״̬
shop.buyProducts( // Ìá½»apiÇëÇ󣬲¢´«Èë³É¹¦Óëʧ°ÜµÄcb-func
products,
() => commit(types.CHECKOUT_SUCCESS), // ÇëÇ󷵻سɹ¦ÔòÉèÖÃÌá½»³É¹¦×´Ì¬
() => commit(types.CHECKOUT_FAILURE, { savedCartItems
}) // ÇëÇó·µ»ØÊ§°ÜÔòÉèÖÃÌύʧ°Ü״̬
)
}
} |
Vue×é¼þÖеã»÷¹ºÂòÖ´Ðе±Ç°moduleµÄdispatch·½·¨£¬´«ÈëtypeֵΪ 'checkout'£¬payloadֵΪ
'products'£¬ÔÚÔ´ÂëÖÐdispatch·½·¨ÔÚËùÓÐ×¢²á¹ýµÄactionsÖвéÕÒ'checkout'µÄ¶ÔÓ¦Ö´ÐÐÊý×飬ȡ³öÑ»·Ö´ÐС£Ö´ÐеÄÊDZ»·â×°¹ýµÄ±»ÃüÃûΪwrappedActionHandlerµÄ·½·¨£¬ÕæÕý´«ÈëµÄcheckoutµÄÖ´Ðк¯ÊýÔÚwrappedActionHandlerÕâ¸ö·½·¨Öб»Ö´ÐУ¬Ô´ÂëÈçÏ£¨×¢£ºÇ°ÃæÌù¹ý£¬ÕâÀïÔÙ¿´Ò»´Î£©£º
function wrappedActionHandler
(payload, cb) {
let res = handler({
dispatch: local.dispatch,
commit: local.commit,
getters: local.getters,
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload, cb)
if (!isPromise(res)) {
res = Promise.resolve(res)
}
if (store._devtoolHook) {
return res.catch(err => {
store._devtoolHook.emit('vuex:error', err)
throw err
})
} else {
return res
}
} |
handlerÔÚÕâÀï¾ÍÊÇ´«ÈëµÄcheckoutº¯Êý£¬ÆäÖ´ÐÐÐèÒªµÄcommitÒÔ¼°state¾ÍÊÇÔÚÕâÀï±»´«È룬payloadÒ²´«ÈëÁË£¬ÔÚʵÀýÖжÔÓ¦½ÓÊյIJÎÊýÃûΪproducts¡£commitµÄÖ´ÐÐÒ²ÊÇͬÀíµÄ£¬ÊµÀýÖÐcheckout»¹½øÐÐÁËÒ»´Îcommit²Ù×÷£¬Ìá½»Ò»´ÎtypeֵΪtypes.CHECKOUT_REQUESTµÄÐ޸ģ¬ÒòΪmutationÃû×ÖÊÇΨһµÄ£¬ÕâÀï½øÐÐÁ˳£Á¿ÐÎʽµÄµ÷Ó㬷ÀÖ¹ÃüÃûÖØ¸´£¬Ö´ÐиúÔ´Âë·ÖÎöÖÐÒ»Ö£¬µ÷ÓÃ
function wrappedMutationHandler (payload) { handler(local.state,
payload) } ·â×°º¯ÊýÀ´Êµ¼Êµ÷ÓÃÅäÖõÄmutation·½·¨¡£
¿´µ½ÍêÔ´Âë·ÖÎöºÍÉÏÃæµÄСʵÀý£¬Ó¦¸ÃÄÜÀí½âdispatch actionºÍcommit mutationµÄ¹¤×÷ÔÀíÁË¡£½Ó×Å¿´Ô´Â룬¿´¿´gettersÊÇÈçºÎʵÏÖstateʵʱ·ÃÎʵġ£
4.6 store._vm×é¼þÉèÖÃ
Ö´ÐÐÍê¸÷moduleµÄinstallºó£¬Ö´ÐÐresetStoreVM·½·¨£¬½øÐÐstore×é¼þµÄ³õʼ»¯¡£
// initialize
the store vm, which is responsible for the reactivity
// (also registers _wrappedGetters as computed
properties)
resetStoreVM(this, state) |
×ÛºÏÇ°ÃæµÄ·ÖÎö¿ÉÒÔÁ˽⵽£¬VuexÆäʵ¹¹½¨µÄ¾ÍÊÇÒ»¸öÃûΪstoreµÄvm×é¼þ£¬ËùÓÐÅäÖõÄstate¡¢actions¡¢mutationsÒÔ¼°getters¶¼ÊÇÆä×é¼þµÄÊôÐÔ£¬ËùÓеIJÙ×÷¶¼ÊǶÔÕâ¸övm×é¼þ½øÐеġ£
Ò»Æð¿´ÏÂresetStoreVM·½·¨µÄÄÚ²¿ÊµÏÖ¡£
function resetStoreVM
(store, state) {
const oldVm = store._vm // »º´æÇ°vm×é¼þ
// bind store public getters
store.getters = {}
const wrappedGetters = store._wrappedGetters
const computed = {}
// Ñ»·ËùÓд¦Àí¹ýµÄgetters£¬²¢Ð½¨computed¶ÔÏó½øÐд洢£¬Í¨¹ýObject.defineProperty·½·¨Îªgetters¶ÔÏó½¨Á¢ÊôÐÔ£¬Ê¹µÃÎÒÃÇͨ¹ýthis.$store.getters.xxxgetterÄܹ»·ÃÎʵ½¸Ãgetters
forEachValue(wrappedGetters, (fn, key) =>
{
// use computed to leverage its lazy-caching
mechanism
computed[key] = () => fn(store)
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true // for local getters
})
})
// use a Vue instance to store the state tree
// suppress warnings just in case the user has
added
// some funky global mixins
const silent = Vue.config.silent
// ÔÝʱ½«VueÉèΪ¾²Ä¬Ä£Ê½£¬±ÜÃⱨ³öÓû§¼ÓÔØµÄijЩ²å¼þ´¥·¢µÄ¾¯¸æ
Vue.config.silent = true
// ÉèÖÃеÄstoreVm£¬½«µ±Ç°³õʼ»¯µÄstateÒÔ¼°getters×÷ΪcomputedÊôÐÔ£¨¸Õ¸Õ±éÀúÉú³ÉµÄ£©
store._vm = new Vue({
data: { state },
computed
})
// »Ö¸´VueµÄģʽ
Vue.config.silent = silent
// enable strict mode for new vm
if (store.strict) {
// ¸Ã·½·¨¶ÔstateÖ´ÐÐ$watchÒÔ½ûÖ¹´ÓmutationÍⲿÐÞ¸Ästate
enableStrictMode(store)
}
// Èô²»Êdzõʼ»¯¹ý³ÌÖ´Ðеĸ÷½·¨£¬½«¾ÉµÄ×é¼þstateÉèÖÃΪnull£¬Ç¿ÖƸüÐÂËùÓмàÌýÕß(watchers)£¬´ý¸üÐÂÉúЧ£¬DOM¸üÐÂÍê³Éºó£¬Ö´ÐÐvm×é¼þµÄdestroy·½·¨½øÐÐÏú»Ù£¬¼õÉÙÄÚ´æµÄÕ¼ÓÃ
if (oldVm) {
// dispatch changes in all subscribed watchers
// to force getter re-evaluation.
store._withCommit(() => {
oldVm.state = null
})
Vue.nextTick(() => oldVm.$destroy())
}
} |
resetStoreVm·½·¨´´½¨Á˵±Ç°storeʵÀýµÄ_vm×é¼þ£¬ÖÁ´Ëstore¾Í´´½¨Íê±ÏÁË¡£ÉÏÃæ´úÂëÉæ¼°µ½ÁËÑϸñģʽµÄÅжϣ¬¿´Ò»ÏÂÑϸñģʽÈçºÎʵÏֵġ£
function enableStrictMode
(store) {
store._vm.$watch('state', () => {
assert(store._committing, `Do not mutate vuex
store state outside mutation handlers.`)
}, { deep: true, sync: true })
} |
ºÜ¼òµ¥µÄÓ¦Ó㬼àÊÓstateµÄ±ä»¯£¬Èç¹ûûÓÐͨ¹ý this._withCommit() ·½·¨½øÐÐstateÐ޸ģ¬Ôò±¨´í¡£
4.7 plugin×¢Èë
×îºóÖ´ÐÐpluginµÄÖ²Èë¡£
plugins.concat(devtoolPlugin).forEach(plugin
=> plugin(this)) |
devtoolPluginÌṩµÄ¹¦ÄÜÓÐ3¸ö£º
// 1. ´¥·¢Vuex×é¼þ³õʼ»¯µÄhook
devtoolHook.emit('vuex:init', store)
// 2. Ìṩ¡°Ê±¿Õ´©Ëó¡±¹¦ÄÜ£¬¼´state²Ù×÷µÄǰ½øºÍµ¹ÍË
devtoolHook.on('vuex:travel-to-state', targetState
=> {
store.replaceState(targetState)
})
// 3. mutation±»Ö´ÐÐʱ£¬´¥·¢hook£¬²¢Ìṩ±»´¥·¢µÄmutationº¯ÊýºÍµ±Ç°µÄstate״̬
store.subscribe((mutation, state) => {
devtoolHook.emit s('vuex:mutation', mutation,
state)
}) |
Ô´Âë·ÖÎöµ½ÕâÀVuex¿ò¼ÜµÄʵÏÖÔÀí»ù±¾¶¼ÒѾ·ÖÎöÍê±Ï¡£
Îå¡¢×ܽá
×îºóÎÒÃǻعýÀ´¿´ÎÄÕ¿ªÊ¼Ìá³öµÄ5¸öÎÊÌâ¡£
1. ÎÊ£ºÊ¹ÓÃVuexÖ»ÐèÖ´ÐÐ Vue.use(Vuex)£¬²¢ÔÚVueµÄÅäÖÃÖд«ÈëÒ»¸östore¶ÔÏóµÄʾÀý£¬storeÊÇÈçºÎʵÏÖ×¢ÈëµÄ£¿
´ð£ºVue.use(Vuex) ·½·¨Ö´ÐеÄÊÇinstall·½·¨£¬ËüʵÏÖÁËVueʵÀý¶ÔÏóµÄinit·½·¨·â×°ºÍ×¢È룬ʹ´«ÈëµÄstore¶ÔÏó±»ÉèÖõ½VueÉÏÏÂÎÄ»·¾³µÄ$storeÖС£Òò´ËÔÚVue
ComponentÈÎÒâµØ·½¶¼Äܹ»Í¨¹ýthis.$store·ÃÎʵ½¸Ãstore¡£
2. ÎÊ£ºstateÄÚ²¿Ö§³ÖÄ£¿éÅäÖúÍÄ£¿éǶÌ×£¬ÈçºÎʵÏֵģ¿
´ð£ºÔÚstore¹¹Ôì·½·¨ÖÐÓÐmakeLocalContext·½·¨£¬ËùÓÐmodule¶¼»áÓÐÒ»¸ölocal
context£¬¸ù¾ÝÅäÖÃʱµÄpath½øÐÐÆ¥Åä¡£ËùÒÔÖ´ÐÐÈçdispatch('submitOrder',
payload)ÕâÀàactionʱ£¬Ä¬ÈϵÄÄõ½¶¼ÊÇmoduleµÄlocal state£¬Èç¹ûÒª·ÃÎÊ×îÍâ²ã»òÕßÊÇÆäËûmoduleµÄstate£¬Ö»ÄÜ´ÓrootState°´ÕÕpath·¾¶Öð²½½øÐзÃÎÊ¡£
3. ÎÊ£ºÔÚÖ´ÐÐdispatch´¥·¢action(commitͬÀí)µÄʱºò£¬Ö»Ðè´«Èë(type,
payload)£¬actionÖ´Ðк¯ÊýÖеÚÒ»¸ö²ÎÊýstore´ÓÄÄÀï»ñÈ¡µÄ£¿
´ð£ºstore³õʼ»¯Ê±£¬ËùÓÐÅäÖõÄactionºÍmutationÒÔ¼°getters¾ù±»·â×°¹ý¡£ÔÚÖ´ÐÐÈçdispatch('submitOrder',
payload)µÄʱºò£¬actionsÖÐtypeΪsubmitOrderµÄËùÓд¦Àí·½·¨¶¼ÊDZ»·â×°ºóµÄ£¬ÆäµÚÒ»¸ö²ÎÊýΪµ±Ç°µÄstore¶ÔÏó£¬ËùÒÔÄܹ»»ñÈ¡µ½
{ dispatch, commit, state, rootState } µÈÊý¾Ý¡£
4. ÎÊ£ºVuexÈçºÎÇø·ÖstateÊÇÍⲿֱ½ÓÐ޸쬻¹ÊÇͨ¹ýmutation·½·¨Ð޸ĵģ¿
´ð£ºVuexÖÐÐÞ¸ÄstateµÄΨһÇþµÀ¾ÍÊÇÖ´ÐÐ commit('xx', payload) ·½·¨£¬Æäµ×²ãͨ¹ýÖ´ÐÐ
this._withCommit(fn) ÉèÖÃ_committing±êÖ¾±äÁ¿Îªtrue£¬È»ºó²ÅÄÜÐÞ¸Ästate£¬ÐÞ¸ÄÍê±Ï»¹ÐèÒª»¹Ô_committing±äÁ¿¡£ÍⲿÐÞ¸ÄËäÈ»Äܹ»Ö±½ÓÐÞ¸Ästate£¬µ«ÊDz¢Ã»ÓÐÐÞ¸Ä_committing±ê־룬ËùÒÔÖ»ÒªwatchÒ»ÏÂstate£¬state
changeʱÅжÏÊÇ·ñ_committingֵΪtrue£¬¼´¿ÉÅжÏÐ޸ĵĺϷ¨ÐÔ¡£
5. ÎÊ£ºµ÷ÊÔʱµÄ"ʱ¿Õ´©Ëó"¹¦ÄÜÊÇÈçºÎʵÏֵģ¿
´ð£ºdevtoolPluginÖÐÌṩÁ˴˹¦ÄÜ¡£ÒòΪdevģʽÏÂËùÓеÄstate change¶¼»á±»¼Ç¼ÏÂÀ´£¬'ʱ¿Õ´©Ëó'
¹¦ÄÜÆäʵ¾ÍÊǽ«µ±Ç°µÄstateÌæ»»Îª¼Ç¼ÖÐij¸öʱ¿ÌµÄstate״̬£¬ÀûÓà store.replaceState(targetState)
·½·¨½«Ö´ÐÐthis._vm.state = state ʵÏÖ¡£
Ô´ÂëÖл¹ÓÐһЩ¹¤¾ßº¯ÊýÀàËÆregisterModule¡¢unregisterModule¡¢hotUpdate¡¢watchÒÔ¼°subscribeµÈ£¬ÈçÓÐÐËȤ¿ÉÒÔ´ò¿ªÔ´Âë¿´¿´£¬ÕâÀï²»ÔÙϸÊö¡£
|