一、 Vuex概念

1、 Vuex是什么?

  • Vuex是专门为Vuejs应用程序设计的状态管理工具。采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

2、 Vuex的具体工作:

  • vuex是一种状态管理机制,将全局组件的共享状态抽取出来为一个store,以一个单例模式存在,应用任何一个组件中都可以使用
  • vuex更改state的唯一途径是通过mutation,mutation需要commit触发,action实际触发是mutation,其中mutation处理同步任务,action处理异步任务

3、 Vuex 的属性包含以下6个:

  • state: 存储的单一状态,存储的基本数据
  • getters是store的计算属性,对state的加工,是派生出来的数据。就像computed计算属性一样,getter返回的值会根据它的依赖被缓存起来,只有当它的依赖值发生改变才会被重新计算
  • mutations: 提交更改数据,使用store.commit方法更改state存储的状态(mutations同步函数)
  • actions: 装饰器,提交mutation,不是直接变更状态(actions可以包含任何异步操作)
  • module: store分隔的模块,每个模块都有自己的state、getters、mutations、actions
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 的状态

(6) 辅助函数

  • Vuex提供了mapState、MapGetters、MapActions、mapMutations等辅助函数给开发在vm中处理store

4、 Vuex使用方法:

  • 开始 ----> 安装Vuex----> 实例化Vuex.Store----> 注入store,挂载Vue实例
import Vuex from 'vuex';
Vue.use(Vuex);     
let store = new Vuex.Store({     // 2. 实例化store,调用install方法
	state,
	getters,
	mutations,
	actions,
	plugins
})
new Vue({     // 注入store,挂载vue实例
	store,
	render:h=>h(app)
}).$mount('#app');

二、 Vuex实现原理

通过以下三个方面来阐述vuex的实现原理:

  • store是怎么注册的?
  • mutation,commit是怎么实现的?
  • 辅助函数是怎么实现的?

2-1、 store是怎么注册的?

1、 Vuex在vue的生命周期中的初始化钩子前插入一段Vuex初始化代码,给Vue的实例注入一个$store的属性,这就是为什么我们在Vue的组件中可以通过this.$store.xxx,访问到Vuex的各种数据和状态

export default function(Vue) {
	// 获取当前Vue的版本
	const version = Number(Vue.version.split('.')[0])

	if(version >= 2) {
		// 2.x通过hook的方式注入
		Vue.mixin({ beforeCreate: vuexInit })
	} else {
		// 兼容1.x
		//使用自定义的_init方法替换Vue对象原型的_init方法,实现注入
			const _init = Vue.prototype._init
		    Vue.prototype._init = function (options = {}) {
		      options.init = options.init
		        ? [vuexInit].concat(options.init)
		        : vuexInit
		      _init.call(this, options)
		    }
		}

	function vuexInit () {
		const options = this.$options
		// store 注入
		if (options.store) {
			this.$store = typeof options.store === 'function'? options.store() : options.store()
		} else if (options.parent && options.parent.$store) {
			// 子组件从其父组件引用$store属性
			this.$store = options.parent.$store
		}
	}
}

2-2、 mutaions是怎么实现的?

function registerMutation (store, type, handler, local) {
	// 获取 type(module.mutations的key) 对应的mutations,没有就创建一个空数组
	const entry = store._mutations[type] || (store._mutations[type] = [])
	// push处理过的mutation handler
	entry.push(function wrappedMutationHandler (payload) {
		// 调用用户定义的handler,并传入state和payload
		handler.call(store, local.state, payload)
	}
}
  • registerMutation 是对store的mutation的初始化
  • 接受4个参数,store为当前Store实例,type为mutation的key,handler为mutation执行的回调函数,path为当前模块的路径

mutation的作用就是同步修改当前模块的state

  • 函数首先通过type拿到对应的mutation对象数组,
  • 然后把一个mutation的包装函数push到这个数组中
  • 这个函数接收一个参数payload,这就是我们在定义mutation的时候接收的额外参数
  • 这个函数执行的时候会调用mutation的回调函数
  • 并通过getNestedState(store.state,path)方法得到当前模块的state,和playload一起作为回调函数的参数

2-3、 commit是怎么实现的?

mutation是通过commit来触发的

commit (_type,_paylod,_options) {
	// 解析参数
	const {
		type,
		payload,
		options
	} = unifyObjectStyle(_type,_payload,_options)

	// 根据 type 获取所有对应的处理过的mutation函数集合
	const mutation = { type, payload }
	const entry = this._mutations[type]
	if (!entry) {
		if (process.env.NODE._ENV !== 'production') {
			console.error(`[vuex] unknown mutation type: ${type}`)
		}
		return
	}
	// 执行mutation函数
	this._withCommit(() => {
		entry.forEach(function commitIterator (handler) {
			handler(payload)
		})
	})

	// 执行所有的订阅者函数
	this._subscribers.forEach(sub => sub(mutations, this.state))

	if (
		process.env.NODE_ENV== ’production‘ &&options && options.silent
	){
		console.warn(
			`[vuex] mutation type: ${type}.Silent option has been removed.` + `Use the filter functionablity in the vue-devtools`
		)
	}
		
}
  • commit支持3个参数,type表示mutation的类型,payload表示额外的参数
  • 根据type查找对应的mutation,找不到就输出一条错误信息,否则遍历这个type对应的mutation对象数组,执行handler(payload)方法,这个方法就是之前定义的wrappedMutationHandler(handler), 执行它就相当于执行了registerMutation注册的回调函数

2-4、 mutation和action有什么区别?

2-4-1 mutation

1、 mutation: 更改Vuex的store中的状态的唯一方法是提交mutation
2、 Vuex中的mutation非常类似于: 每个mutation都有一个字符串的事件类型(type) 和一个回调函数(handler)
3、 这个回调函数就是我们实际进行状态更改的地方,并且它会接收state作为第一个参数

const store = new Vue.Store ({
	state: {
		count: 1
	},
	mutations: {
		increment (state) {
			// 变更状态
			state.count++
		}
	}
})

4、 不能直接调用一个mutation handler
5、 这个选项更像是事件注册:“当触发一个类型为increment的mutation时,调用此函数”
6、 要唤醒一个mutation handler,需要以相应的type调用store.commit方法
store.commit('increment')

2-4-2 Actions

1、 Action: 类似于mutation,不同在于:

  • Action提交的是mutation,而不是直接变更状态
  • Action可以包含任意异步操作
const store = new Vuex.Store({
	state: {
		count: 0
	},
	mutations: {
		increment (state) {
			state.count++
		}
	},
	actions: {
		increment (context) {
			content.commit('increment')
		}
	}
})
  • 事实上在vuex里面actions只是一个架构性的概念,只是一个函数
  • vuex真正限制你的只有mutation必须是同步的的这一点
Logo

前往低代码交流专区

更多推荐