@@ -14,7 +14,8 @@ import {
14
14
isObject ,
15
15
isArray ,
16
16
EMPTY_OBJ ,
17
- NOOP
17
+ NOOP ,
18
+ hasOwn
18
19
} from '@vue/shared'
19
20
import { computed } from './apiComputed'
20
21
import { watch , WatchOptions , WatchCallback } from './apiWatch'
@@ -75,11 +76,16 @@ export interface ComponentOptionsBase<
75
76
directives ?: Record < string , Directive >
76
77
inheritAttrs ?: boolean
77
78
79
+ // Internal ------------------------------------------------------------------
80
+
81
+ // marker for AsyncComponentWrapper
82
+ __asyncLoader ?: ( ) => Promise < Component >
83
+ // cache for merged $options
84
+ __merged ?: ComponentOptions
85
+
78
86
// type-only differentiator to separate OptionWithoutProps from a constructor
79
87
// type returned by defineComponent() or FunctionalComponent
80
88
call ?: never
81
- // marker for AsyncComponentWrapper
82
- __asyncLoader ?: ( ) => Promise < Component >
83
89
// type-only differentiators for built-in Vnode types
84
90
__isFragment ?: never
85
91
__isPortal ?: never
@@ -161,7 +167,8 @@ export interface LegacyOptions<
161
167
C extends ComputedOptions ,
162
168
M extends MethodOptions
163
169
> {
164
- el ?: any
170
+ // allow any custom options
171
+ [ key : string ] : any
165
172
166
173
// state
167
174
// Limitation: we cannot expose RawBindings on the `this` context for data
@@ -501,3 +508,31 @@ function createWatcher(
501
508
warn ( `Invalid watch option: "${ key } "` )
502
509
}
503
510
}
511
+
512
+ export function resolveMergedOptions (
513
+ instance : ComponentInternalInstance
514
+ ) : ComponentOptions {
515
+ const raw = instance . type as ComponentOptions
516
+ const { __merged, mixins, extends : extendsOptions } = raw
517
+ if ( __merged ) return __merged
518
+ const globalMixins = instance . appContext . mixins
519
+ if ( ! globalMixins && ! mixins && ! extendsOptions ) return raw
520
+ const options = { }
521
+ globalMixins && globalMixins . forEach ( m => mergeOptions ( options , m , instance ) )
522
+ extendsOptions && mergeOptions ( options , extendsOptions , instance )
523
+ mixins && mixins . forEach ( m => mergeOptions ( options , m , instance ) )
524
+ mergeOptions ( options , raw , instance )
525
+ return ( raw . __merged = options )
526
+ }
527
+
528
+ function mergeOptions ( to : any , from : any , instance : ComponentInternalInstance ) {
529
+ const strats = instance . appContext . config . optionMergeStrategies
530
+ for ( const key in from ) {
531
+ const strat = strats && strats [ key ]
532
+ if ( strat ) {
533
+ to [ key ] = strat ( to [ key ] , from [ key ] , instance . proxy , key )
534
+ } else if ( ! hasOwn ( to , key ) ) {
535
+ to [ key ] = from [ key ]
536
+ }
537
+ }
538
+ }
0 commit comments