Vuex 的原理
疑问 1:Vuex 的 store 是如何挂载注入到组件中的?
1. 在 vue 项目中先安装 vuex
npm install vuex --save
2. 利用 vue 的插件机制
使用 Vue.use(vuex) 时,会调用 vuex 的 install 方法装载 vuex。install 方法中的 applyMixin 方法使用 vue 的混入机制(mixin),在 vue 的生命周期 beforeCreate 钩子前混入 vuexInit 方法。
// 简化版 install
function install(Vue) {
Vue.mixin({
beforeCreate: vuexInit
})
}
function vuexInit() {
const options = this.$options
if (options.store) {
// 根实例:直接把 store 挂到 this 上
this.$store = options.store
} else if (options.parent && options.parent.$store) {
// 子组件:继承父组件的 $store 引用
this.$store = options.parent.$store
}
}
分析源码可以知道,vuex 利用 vue 的 mixin 混入机制,在 beforeCreate 钩子前混入 vuexInit 方法。vuexInit 方法实现了 store 注入 vue 组件实例,并注册了 vuex store 的引用属性 $store,让所有组件都能通过 this.$store 访问 store。
疑问 2:vuex 的 state 和 getters 是如何映射到各个组件实例中响应式更新状态?
从源码可以看出,Vuex 的 state 状态是响应式,借助了 vue 的 data 是响应式 —— 将 state 存入 vue 实例组件的 data 中。Vuex 的 getters 则是借助 vue 的计算属性(computed)实现数据实时监听。
// 简化版:state 通过响应式 data 实现
function resetStoreVM(store, state) {
store._vm = new Vue({
data: { $$state: state },
computed
})
// 代理 getters
Object.keys(store.getters).forEach(key => {
Object.defineProperty(store, key, {
get: () => store._vm[key]
})
})
}
补充:Vuex 5 / Pinia 的实现思路则改为:state 通过
reactive/ref暴露给组件,getters 就是普通的 computed,不再依赖"挂在 data 上"这种取巧实现,类型推导也更好。
来源整理自:vue3js.cn 面试官系列



