ae73f80bfd976227df0ca63e77b7a5c623973e8e8ed08e0f9a5ad73558b88f7ed6729cd300b6ade89d2e06fd04f45bdf85172b702fa78d9faee65c32450d08 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* @flow */
  2. import { ASSET_TYPES } from 'shared/constants'
  3. import { defineComputed, proxy } from '../instance/state'
  4. import { extend, mergeOptions, validateComponentName } from '../util/index'
  5. export function initExtend (Vue: GlobalAPI) {
  6. /**
  7. * Each instance constructor, including Vue, has a unique
  8. * cid. This enables us to create wrapped "child
  9. * constructors" for prototypal inheritance and cache them.
  10. */
  11. Vue.cid = 0
  12. let cid = 1
  13. /**
  14. * Class inheritance
  15. */
  16. Vue.extend = function (extendOptions: Object): Function {
  17. extendOptions = extendOptions || {}
  18. const Super = this
  19. const SuperId = Super.cid
  20. const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
  21. if (cachedCtors[SuperId]) {
  22. return cachedCtors[SuperId]
  23. }
  24. const name = extendOptions.name || Super.options.name
  25. if (process.env.NODE_ENV !== 'production' && name) {
  26. validateComponentName(name)
  27. }
  28. const Sub = function VueComponent (options) {
  29. this._init(options)
  30. }
  31. Sub.prototype = Object.create(Super.prototype)
  32. Sub.prototype.constructor = Sub
  33. Sub.cid = cid++
  34. Sub.options = mergeOptions(
  35. Super.options,
  36. extendOptions
  37. )
  38. Sub['super'] = Super
  39. // For props and computed properties, we define the proxy getters on
  40. // the Vue instances at extension time, on the extended prototype. This
  41. // avoids Object.defineProperty calls for each instance created.
  42. if (Sub.options.props) {
  43. initProps(Sub)
  44. }
  45. if (Sub.options.computed) {
  46. initComputed(Sub)
  47. }
  48. // allow further extension/mixin/plugin usage
  49. Sub.extend = Super.extend
  50. Sub.mixin = Super.mixin
  51. Sub.use = Super.use
  52. // create asset registers, so extended classes
  53. // can have their private assets too.
  54. ASSET_TYPES.forEach(function (type) {
  55. Sub[type] = Super[type]
  56. })
  57. // enable recursive self-lookup
  58. if (name) {
  59. Sub.options.components[name] = Sub
  60. }
  61. // keep a reference to the super options at extension time.
  62. // later at instantiation we can check if Super's options have
  63. // been updated.
  64. Sub.superOptions = Super.options
  65. Sub.extendOptions = extendOptions
  66. Sub.sealedOptions = extend({}, Sub.options)
  67. // cache constructor
  68. cachedCtors[SuperId] = Sub
  69. return Sub
  70. }
  71. }
  72. function initProps (Comp) {
  73. const props = Comp.options.props
  74. for (const key in props) {
  75. proxy(Comp.prototype, `_props`, key)
  76. }
  77. }
  78. function initComputed (Comp) {
  79. const computed = Comp.options.computed
  80. for (const key in computed) {
  81. defineComputed(Comp.prototype, key, computed[key])
  82. }
  83. }