Skip to content

Commit e1342df

Browse files
committed
fix(setup): setup hook should be called before beforeCreate
fix vuejs#12802 Note this commit moves the initialization of injections and props to before the invocation of beforeCreate. This should not cause breakage because props and inject normalization has always been done before beforeCreate, so code that attempts to modifiy props/inject options inside beforeCreate should have never worked.
1 parent 0d6d972 commit e1342df

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

src/core/instance/init.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import config from '../config'
22
import { initProxy } from './proxy'
3-
import { initState } from './state'
3+
import { initProps, initState } from './state'
44
import { initRender } from './render'
55
import { initEvents } from './events'
66
import { mark, measure } from '../util/perf'
@@ -10,6 +10,7 @@ import { extend, mergeOptions, formatComponentName } from '../util/index'
1010
import type { Component } from 'types/component'
1111
import type { InternalComponentOptions } from 'types/options'
1212
import { EffectScope } from 'v3/reactivity/effectScope'
13+
import { initSetup } from '../../v3/apiSetup'
1314

1415
let uid = 0
1516

@@ -59,8 +60,12 @@ export function initMixin(Vue: typeof Component) {
5960
initLifecycle(vm)
6061
initEvents(vm)
6162
initRender(vm)
62-
callHook(vm, 'beforeCreate', undefined, false /* setContext */)
63+
64+
const opts = vm.$options
6365
initInjections(vm) // resolve injections before data/props
66+
initProps(vm, opts.props)
67+
initSetup(vm)
68+
callHook(vm, 'beforeCreate', undefined, false /* setContext */)
6469
initState(vm)
6570
initProvide(vm) // resolve provide after data/props
6671
callHook(vm, 'created')

src/core/instance/state.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import config from '../config'
22
import Watcher from '../observer/watcher'
33
import Dep, { pushTarget, popTarget } from '../observer/dep'
44
import { isUpdatingChildComponent } from './lifecycle'
5-
import { initSetup } from 'v3/apiSetup'
65

76
import {
87
set,
@@ -51,11 +50,6 @@ export function proxy(target: Object, sourceKey: string, key: string) {
5150

5251
export function initState(vm: Component) {
5352
const opts = vm.$options
54-
if (opts.props) initProps(vm, opts.props)
55-
56-
// Composition API
57-
initSetup(vm)
58-
5953
if (opts.methods) initMethods(vm, opts.methods)
6054
if (opts.data) {
6155
initData(vm)
@@ -69,7 +63,8 @@ export function initState(vm: Component) {
6963
}
7064
}
7165

72-
function initProps(vm: Component, propsOptions: Object) {
66+
export function initProps(vm: Component, propsOptions: Object | undefined) {
67+
if (!propsOptions) return
7368
const propsData = vm.$options.propsData || {}
7469
const props = (vm._props = shallowReactive({}))
7570
// cache prop keys so that future props updates can iterate using Array

test/unit/features/v3/apiSetup.spec.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ describe('api: setup context', () => {
263263
}).$mount()
264264
expect(spy).toHaveBeenCalled()
265265
})
266-
266+
267267
// #12561
268268
it('setup props should be reactive', () => {
269269
const msg = ref('hi')
@@ -333,4 +333,30 @@ describe('api: setup context', () => {
333333
await nextTick()
334334
expect(_listeners.foo()).toBe(2)
335335
})
336+
337+
// #12802
338+
it('should be called before all lifecycle hooks', () => {
339+
const calls: string[] = []
340+
341+
Vue.mixin({
342+
beforeCreate() {
343+
calls.push('global beforeCreate')
344+
}
345+
})
346+
347+
new Vue({
348+
beforeCreate() {
349+
calls.push('component beforeCreate')
350+
},
351+
setup() {
352+
calls.push('setup')
353+
}
354+
})
355+
356+
expect(calls).toEqual([
357+
'setup',
358+
'global beforeCreate',
359+
'component beforeCreate'
360+
])
361+
})
336362
})

0 commit comments

Comments
 (0)