Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Vuex¿ò¼ÜÔ­ÀíÓëÔ´Âë·ÖÎö
 
À´Ô´£ºÃÀÍż¼ÊõµãÆÀÖÐÐÄ ·¢²¼ÓÚ£º2017-6-27
  3632  次浏览      29
 

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 ±äÁ¿£¬ÓÃÓÚÅжÏÊÇ·ñÒѾ­×°ÔغͼõÉÙÈ«¾Ö×÷ÓÃÓò²éÕÒ¡£

let 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µÈ£¬ÈçÓÐÐËȤ¿ÉÒÔ´ò¿ªÔ´Âë¿´¿´£¬ÕâÀï²»ÔÙϸÊö¡£

   
3632 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì