「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
模拟 Vuex
接上回,本章要进行 手写Vuex
的 install
、store
部分方法
install 方法
install
是一个对于一个Vue
插件,都需要具备的一个方法。在我们实现Vuex
的过程中,我们需要在此方法中,需要将Vue
实例保存起来,方便我们之后的调用。然后我们需要将store
赋值给Vue.prototype.$store
。
如何保存Vue
实例?
在vue
的官方文档中也很明确的说到:
Vue.js 的插件应该暴露一个
install
方法。这个方法的第一个参数是Vue
构造器,第二个参数是一个可选的选项对象
那么我们只需要如此操作即可:
let _Vue = null
function install (Vue) {
_Vue = Vue
}
复制代码
将store
赋值给Vue.prototype.$store
在将store
赋值给Vue.prototype.$store
后,项目中的所有组件都可以通过this.$store
来获取Vuex
下面的仓库,从而可以在所有组件中共享状态。
我们可以通过混入beforeCreate
来获取Vue
实例,获取选项中的Vue
对象
function install (Vue) {
_Vue = Vue
_Vue.mixin({
beforeCreate () {
// 如果已经注册了,就不需要再次进行注册了
if (this.$options.store) {
_Vue.prototype.$store = this.$options.store
}
}
})
}
复制代码
到这里 install
方法就结束了
Store 类
需要包含的内容
- state - 响应式的
- getters
- mutations
- actions
- commit 提交 mutations
- dispatch 分发 actions
1.首先需要一个构造函数
-
获得参数
构造函数中,需要初始化时的参数
constructor (options) { const { state = {}, getters = {}, mutations = {}, actions = {} } = options } 复制代码
-
state
转换为响应式然后我们需要将
state
转换为响应式的对象,我们需要调用observable
对数据进行响应式处理:this.state = _Vue.observable(state) 复制代码
-
getters
处理getters
是一个对象,对象中有一些方法,这些方法都需要接受state
参数,并且最终都有一个返回值。一般情况下就是对state
做一些处理后返回,而只有当我们访问了getters
方法时,才会有有值返回,所以我们可以用Object.defineProperty
转换get
this.getters = Object.create(null) Object.keys(getters).forEach(key => { Object.defineProperty(this.getters, key, { get: () => getters[key](state) }) }) 复制代码
-
mutations、actions 只需要存储到对应的方法中在
commit
、dispatch
中获取就好
如此命名主要是不希望外部可以随便访问
this._mutations = mutations
this._actions = actions
复制代码
commit
、dispatch
commit (type, payload) {
this._mutations[type](this.state, payload)
}
dispatch (type, payload) {
this._actions[type](this, payload)
}
复制代码
五、总结
最后我们回过来看文章开始提出的5个问题。
1. 问:使用Vuex只需执行 Vue.use(Vuex)
,并在Vue的配置中传入一个store对象的示例,store是如何实现注入的?
答:
Vue.use(Vuex)
方法执行的是install方法,它实现了Vue实例对象的init方法封装和注入,使传入的store对象被设置到Vue上下文环境的 store`访问到该store。
2. 问:在执行dispatch触发action(commit同理)的时候,只需传入(type, payload),action执行函数中第一个参数store从哪里获取的?
答:store初始化时,所有配置的action和mutation以及getters均被封装过。在执行如
dispatch('submitOrder', payload)
的时候,actions中type为submitOrder的所有处理方法都是被封装后的,其第一个参数为当前的store对象,所以能够获取到{ dispatch, commit, state, rootState }
等数据。
源码中还有一些工具函数,如有兴趣可以打开源码看看,这里不再细述。
我们本章进行模拟的主要目的还是,想要了解Vuex
的工作基本流程