UNPKG

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