Vuex概念+实现原理
(6) 辅助函数4、 Vuex使用方法:二、 Vuex实现原理2-1、 store是怎么注册的?1、Vuex在vue的生命周期中的初始化钩子前插入一段Vuex初始化代码,给Vue的实例注入一个的属性,这就是为什么我们在Vue的组件中可以通过,访问到Vuex的各种数据和状态2-2、 mutaions是怎么实现的?registerMutation 是对store的mutation的初始化接受4个参数,
文章目录
一、 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必须是同步的的这一点
更多推荐
所有评论(0)