Vue 构造器

Vue 的本质是一个构造器

  1. // Vue 构造函数
  2. function Vue(options) {
  3. // 保证了无法直接通过 Vue() 去调用,只能通过 new 的方式去创建实例
  4. if (!(this instanceof Vue)) {
  5. warn('Vue is a constructor and should be called with the `new` keyword');
  6. }
  7. this._init(options);
  8. }
  9. return Vue;

定义静态属性方法

在 initGlobalAPI 中定义全局 api 方法
微信截图_20211111221729.png

  1. export function initGlobalAPI (Vue: GlobalAPI) {
  2. // config
  3. const configDef = {}
  4. configDef.get = () => config
  5. if (process.env.NODE_ENV !== 'production') {
  6. configDef.set = () => {
  7. warn(
  8. 'Do not replace the Vue.config object, set individual fields instead.'
  9. )
  10. }
  11. }
  12. Object.defineProperty(Vue, 'config', configDef)
  13. // exposed util methods.
  14. // NOTE: these are not considered part of the public API - avoid relying on
  15. // them unless you are aware of the risk.
  16. Vue.util = {
  17. warn,
  18. extend,
  19. mergeOptions,
  20. defineReactive
  21. }
  22. Vue.set = set
  23. Vue.delete = del
  24. Vue.nextTick = nextTick
  25. // 2.6 explicit observable API
  26. Vue.observable = <T>(obj: T): T => {
  27. observe(obj)
  28. return obj
  29. }
  30. // 原型上创建了一个指向为空对象的options属性
  31. Vue.options = Object.create(null)
  32. ASSET_TYPES.forEach(type => {
  33. Vue.options[type + 's'] = Object.create(null)
  34. })
  35. // this is used to identify the "base" constructor to extend all plain-object
  36. // components with in Weex's multi-instance scenarios.
  37. Vue.options._base = Vue
  38. extend(Vue.options.components, builtInComponents)
  39. initUse(Vue)
  40. initMixin(Vue)
  41. initExtend(Vue)
  42. initAssetRegisters(Vue)
  43. }

extend 方法实现对象的合并

  1. function extend (to, _from) {
  2. for (var key in _from) {
  3. to[key] = _from[key];
  4. }
  5. return to
  6. }

initMixin 流程

initMixin.9a4f8f37.png

  1. export function initMixin (Vue) {
  2. Vue.prototype._init = function (options) {
  3. const vm = this
  4. // 1. 合并配置
  5. if (options && options._isComponent) {
  6. initInternalComponent(vm, options)
  7. } else {
  8. vm.$options = mergeOptions(
  9. resolveConstructorOptions(vm.constructor),
  10. options || {},
  11. vm
  12. )
  13. }
  14. // 2.render代理
  15. if (process.env.NODE_ENV !== 'production') {
  16. initProxy(vm)
  17. } else {
  18. vm._renderProxy = vm
  19. }
  20. // 3.初始化生命周期、初始化事件中心、初始化inject,
  21. // 初始化state、初始化provide、调用生命周期
  22. vm._self = vm
  23. initLifecycle(vm)
  24. initEvents(vm)
  25. initRender(vm)
  26. callHook(vm, 'beforeCreate')
  27. initInjections(vm)
  28. initState(vm)
  29. initProvide(vm)
  30. callHook(vm, 'created')
  31. // 4.挂载
  32. if (vm.$options.el) {
  33. vm.$mount(vm.$options.el)
  34. }
  35. }
  36. }

初始化第一步进行合并配置

参考资料

  1. 丰富的选项合并策略
  2. 从 Vue 源码学习 JS 之 this instanceof Vue
  3. initGlobalAPI流程