@@ -79,6 +79,7 @@ import {
79
79
DIRECTIVES ,
80
80
FILTERS
81
81
} from './helpers/resolveAssets'
82
+ import { OptionMergeFunction } from './apiCreateApp'
82
83
83
84
/**
84
85
* Interface for declaring custom options.
@@ -194,11 +195,6 @@ export interface ComponentOptionsBase<
194
195
* @internal
195
196
*/
196
197
__asyncResolved ?: ConcreteComponent
197
- /**
198
- * cache for merged $options
199
- * @internal
200
- */
201
- __merged ?: ComponentOptions
202
198
203
199
// Type differentiators ------------------------------------------------------
204
200
@@ -486,6 +482,28 @@ interface LegacyOptions<
486
482
__differentiator ?: keyof D | keyof C | keyof M
487
483
}
488
484
485
+ type MergedHook < T = ( ( ) => void ) > = T | T [ ]
486
+
487
+ export type MergedComponentOptionsOverride = {
488
+ beforeCreate ?: MergedHook
489
+ created ?: MergedHook
490
+ beforeMount ?: MergedHook
491
+ mounted ?: MergedHook
492
+ beforeUpdate ?: MergedHook
493
+ updated ?: MergedHook
494
+ activated ?: MergedHook
495
+ deactivated ?: MergedHook
496
+ /** @deprecated use `beforeUnmount` instead */
497
+ beforeDestroy ?: MergedHook
498
+ beforeUnmount ?: MergedHook
499
+ /** @deprecated use `unmounted` instead */
500
+ destroyed ?: MergedHook
501
+ unmounted ?: MergedHook
502
+ renderTracked ?: MergedHook < DebuggerHook >
503
+ renderTriggered ?: MergedHook < DebuggerHook >
504
+ errorCaptured ?: MergedHook < ErrorCapturedHook >
505
+ }
506
+
489
507
export type OptionTypesKeys = 'P' | 'B' | 'D' | 'C' | 'M' | 'Defaults'
490
508
491
509
export type OptionTypesType <
@@ -1022,41 +1040,73 @@ export function createWatcher(
1022
1040
}
1023
1041
}
1024
1042
1043
+ /**
1044
+ * Resolve merged options and cache it on the component.
1045
+ * This is done only once per-component since the merging does not involve
1046
+ * instances.
1047
+ */
1025
1048
export function resolveMergedOptions (
1026
1049
instance : ComponentInternalInstance
1027
- ) : ComponentOptions {
1028
- const raw = instance . type as ComponentOptions
1029
- const { __merged, mixins, extends : extendsOptions } = raw
1030
- if ( __merged ) return __merged
1031
- const globalMixins = instance . appContext . mixins
1032
- if ( ! globalMixins . length && ! mixins && ! extendsOptions ) return raw
1033
- const options = { }
1034
- globalMixins . forEach ( m => mergeOptions ( options , m , instance ) )
1035
- mergeOptions ( options , raw , instance )
1036
- return ( raw . __merged = options )
1050
+ ) : ComponentOptions & MergedComponentOptionsOverride {
1051
+ const base = instance . type as ComponentOptions
1052
+ const { mixins, extends : extendsOptions } = base
1053
+ const {
1054
+ mixins : globalMixins ,
1055
+ cache,
1056
+ config : { optionMergeStrategies }
1057
+ } = instance . appContext
1058
+ const cached = cache . get ( base )
1059
+
1060
+ let resolved : ComponentOptions
1061
+
1062
+ if ( cached ) {
1063
+ resolved = cached
1064
+ } else if ( ! globalMixins . length && ! mixins && ! extendsOptions ) {
1065
+ if (
1066
+ __COMPAT__ &&
1067
+ isCompatEnabled ( DeprecationTypes . PRIVATE_APIS , instance )
1068
+ ) {
1069
+ resolved = extend ( { } , base )
1070
+ resolved . parent = instance . parent && instance . parent . proxy
1071
+ resolved . propsData = instance . vnode . props
1072
+ } else {
1073
+ resolved = base
1074
+ }
1075
+ } else {
1076
+ resolved = { }
1077
+ if ( globalMixins . length ) {
1078
+ globalMixins . forEach ( m =>
1079
+ mergeOptions ( resolved , m , optionMergeStrategies )
1080
+ )
1081
+ }
1082
+ mergeOptions ( resolved , base , optionMergeStrategies )
1083
+ }
1084
+
1085
+ cache . set ( base , resolved )
1086
+ return resolved
1037
1087
}
1038
1088
1039
1089
export function mergeOptions (
1040
1090
to : any ,
1041
1091
from : any ,
1042
- instance ?: ComponentInternalInstance | null ,
1043
- strats = instance && instance . appContext . config . optionMergeStrategies
1092
+ strats : Record < string , OptionMergeFunction >
1044
1093
) {
1045
1094
if ( __COMPAT__ && isFunction ( from ) ) {
1046
1095
from = from . options
1047
1096
}
1048
1097
1049
1098
const { mixins, extends : extendsOptions } = from
1050
1099
1051
- extendsOptions && mergeOptions ( to , extendsOptions , instance , strats )
1052
- mixins &&
1053
- mixins . forEach ( ( m : ComponentOptionsMixin ) =>
1054
- mergeOptions ( to , m , instance , strats )
1055
- )
1100
+ if ( extendsOptions ) {
1101
+ mergeOptions ( to , extendsOptions , strats )
1102
+ }
1103
+ if ( mixins ) {
1104
+ mixins . forEach ( ( m : ComponentOptionsMixin ) => mergeOptions ( to , m , strats ) )
1105
+ }
1056
1106
1057
1107
for ( const key in from ) {
1058
1108
if ( strats && hasOwn ( strats , key ) ) {
1059
- to [ key ] = strats [ key ] ( to [ key ] , from [ key ] , instance && instance . proxy , key )
1109
+ to [ key ] = strats [ key ] ( to [ key ] , from [ key ] )
1060
1110
} else {
1061
1111
to [ key ] = from [ key ]
1062
1112
}
0 commit comments