我们在开发vue项目的时候,不同的组件,父子组件之间,兄弟组件之间,根组件App.vue等等,都可以通过Vue.$store
拿到vuex里面的共享数据源。那么这么多不同层级的组件到底是如何保证都拿到同一个store实例呢
?我们从vuex的源码上面浅显的聊聊中间的实现过程
首先在项目入口文件main.js中,我们从./store
引入index.js
,并且把引入的store
作为初始化Vue的一个option
对Vue进行初始化
我们再来看看./store
文件夹中index.js
里面写了什么:
这里面引入了Vuex
,并且调用Vue.use(Vuex)
时候传入了Vuex
。我们知道Vue.use()
是我们vue中使用插件的一种方式,当执行Vue.use(some plugin)
的时候,会执行插件内部的install
方法
我们再来看看vuex
的源码里面install
方法是怎么写的:
这个install
方法就是安装Vuex时候调用的函数,在这个方法中,判断了当前传入的vue实例_Vue是否是之前调用install时缓存的vue实例,如果是同一个实例,就返回警告。
然后我们重点看这行代码:
applyMixin(Vue)
顺藤摸瓜看一下applyMixin
方法是干嘛的:
先检查了一下vue的版本,如果是vue2或者以上的版本,就调用Vue.mixin()
方法,在这个方法里面创建了一个beforeCreate
钩子,这个钩子执行vuexInit
方法。我们继续看vuexInit
方法实现了什么功能:
重点来了!
我们看下这里面的代码,首先获取this.$options
的值,这个值其实就是这个东西,在入口函数里,this.$options
的值就是Vue实例里面的配置项:
在组件中,this.$options
的值就是红框内部的东西
当拿到this.$options
的选项之后,会查找选项中有没有store
这个属性:
目前只有在入口函数main.js的Vue根实例中才有store属性,所以对于根实例,给它定义一个$store
保存的就是this.$options
的store
这个store
就是引入的内容,也就是下面导出的东西,现在已经被挂载到根实例Vue的$this
属性上了
如果不是根组件,比如对于子组件,代码里面是没有store
的,那么就会走下面的逻辑
去查找子组件的父级组件,看看父组件是否存在并且父组件中是否有$store
属性,如果有的话就给子组件自己定义一个属性$store
,然后指向查找到的父组件的$store
这样就实现了每个组件都拿到同一个store实例!
以上都是个人理解,可能存在不对的地方,欢迎大佬们前来吐槽,讨论:D