vuex 源码学习记录
先看 vuex 源码目录
源码都在 src
目录下,入口文件为 index.js
(或 index.esm.js
),当用 import Vuex from 'vuex'
引入 vuex
时,入口就是 index.esm.js
(esm: es6 module),看看里面
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } export { Store, install, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
首先就是引入 Store
和 install
,先看看 install
方法
export function install (_Vue) { // Vue 已经存在并且相等,说明已经 Vuex 已经 install 过 if (Vue && _Vue === Vue) { // 非生产环境报错,vuex已经安装,代码继续执行 if (process.env.NODE_ENV !== 'production') { console.error( '[vuex] already installed. Vue.use(Vuex) should be called only once.' ) } return } Vue = _Vue applyMixin(Vue) }
上述代码逻辑很简单,执行 Vuex.install
时传入 Vue
构造函数,最后再执行 applyMixin(Vue)
但是,通常情况下,我们引入 Vuex
之后,都是执行 Vue.use(vuex)
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
看看 vue
源码
// src/core/global-api/use.js /* @flow */ import { toArray } from '../util/index' export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters const args = toArray(arguments, 1) args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this } }
如果传进来的 plugin
有 install
方法,就执行 install
方法,当然我们也可以直击直接 install
方法,效果是一样的
import Vue from 'vue' import Vuex from 'vuex' Vuex.install(Vue)
再来看看 applyMixin
方法,这个方法在 mixin.js
中
// vuex/src/minx.js export default function (Vue) { const version = Number(Vue.version.split('.')[0]) // 2 if (version >= 2) { // 全局混入了一个 beforeCreate 钩子函数 Vue.mixin({ beforeCreate: vuexInit }) } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. const _init = Vue.prototype._init Vue.prototype._init = function (options = {}) { options.init = options.init ? [vuexInit].concat(options.init) : vuexInit _init.call(this, options) } } /** * Vuex init hook, injected into each instances init hooks list. */ function vuexInit () { const options = this.$options // store 注入 // 使得每个Vue实例下 都有 $store 这个对象(Store 实例,包含一系列方法和属性),且是同一个对象。 // 先是判断 options.store 也就是 这个 // store injection if (options.store) { this.$store = typeof options.store === 'function' ? options.store() : options.store } else if (options.parent && options.parent.$store) { this.$store = options.parent.$store } } }
看看 Vue
的源码中 Vue.mixin
方法
// src/core/global-api/mixin.js /* @flow */ import { mergeOptions } from '../util/index' export function initMixin (Vue: GlobalAPI) { Vue.mixin = function (mixin: Object) { this.options = mergeOptions(this.options, mixin) return this } }
其实就是全局混入了一个 beforeCreate 钩子函数,打印 Vue 实例看看
原文地址:https://segmentfault.com/a/1190000021107665
相关推荐
-
理解javascript装饰器 javascript/jquery
2020-5-20
-
通过focusout事件解决IOS键盘收起时界面不归位的问题 javascript/jquery
2019-7-20
-
vue中实现简易购物车(麻雀小,五脏全) javascript/jquery
2020-6-16
-
TypeScript学习 泛型 javascript/jquery
2019-11-1
-
JavaScript漫谈之深入理解作用域与闭包 javascript/jquery
2019-10-14
-
【译】Web内容如何影响电池的使用 javascript/jquery
2019-10-14
-
深入理解HTTPS工作原理 javascript/jquery
2019-5-3
-
微前端实践(一):基于事件通信机制的微前端通信框架obvious.js javascript/jquery
2020-6-12
-
Git 学习笔记 javascript/jquery
2018-10-18
-
ES6 新特性之Generator javascript/jquery
2019-9-1