Skip to content

Commit cb1bb75

Browse files
committed
fix global mixin props (fix #3957)
1 parent 4b8eb75 commit cb1bb75

File tree

3 files changed

+51
-28
lines changed

3 files changed

+51
-28
lines changed

src/core/instance/init.js

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function initMixin (Vue: Class<Component>) {
2424
initInternalComponent(vm, options)
2525
} else {
2626
vm.$options = mergeOptions(
27-
resolveConstructorOptions(vm),
27+
resolveConstructorOptions(vm.constructor),
2828
options || {},
2929
vm
3030
)
@@ -44,37 +44,36 @@ export function initMixin (Vue: Class<Component>) {
4444
callHook(vm, 'created')
4545
initRender(vm)
4646
}
47+
}
4748

48-
function initInternalComponent (vm: Component, options: InternalComponentOptions) {
49-
const opts = vm.$options = Object.create(resolveConstructorOptions(vm))
50-
// doing this because it's faster than dynamic enumeration.
51-
opts.parent = options.parent
52-
opts.propsData = options.propsData
53-
opts._parentVnode = options._parentVnode
54-
opts._parentListeners = options._parentListeners
55-
opts._renderChildren = options._renderChildren
56-
opts._componentTag = options._componentTag
57-
if (options.render) {
58-
opts.render = options.render
59-
opts.staticRenderFns = options.staticRenderFns
60-
}
49+
function initInternalComponent (vm: Component, options: InternalComponentOptions) {
50+
const opts = vm.$options = Object.create(vm.constructor.options)
51+
// doing this because it's faster than dynamic enumeration.
52+
opts.parent = options.parent
53+
opts.propsData = options.propsData
54+
opts._parentVnode = options._parentVnode
55+
opts._parentListeners = options._parentListeners
56+
opts._renderChildren = options._renderChildren
57+
opts._componentTag = options._componentTag
58+
if (options.render) {
59+
opts.render = options.render
60+
opts.staticRenderFns = options.staticRenderFns
6161
}
62+
}
6263

63-
function resolveConstructorOptions (vm: Component) {
64-
const Ctor = vm.constructor
65-
let options = Ctor.options
66-
if (Ctor.super) {
67-
const superOptions = Ctor.super.options
68-
const cachedSuperOptions = Ctor.superOptions
69-
if (superOptions !== cachedSuperOptions) {
70-
// super option changed
71-
Ctor.superOptions = superOptions
72-
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
73-
if (options.name) {
74-
options.components[options.name] = Ctor
75-
}
64+
export function resolveConstructorOptions (Ctor: Class<Component>) {
65+
let options = Ctor.options
66+
if (Ctor.super) {
67+
const superOptions = Ctor.super.options
68+
const cachedSuperOptions = Ctor.superOptions
69+
if (superOptions !== cachedSuperOptions) {
70+
// super option changed
71+
Ctor.superOptions = superOptions
72+
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
73+
if (options.name) {
74+
options.components[options.name] = Ctor
7675
}
7776
}
78-
return options
7977
}
78+
return options
8079
}

src/core/vdom/create-component.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import Vue from '../instance/index'
44
import VNode from './vnode'
55
import { normalizeChildren } from './helpers/index'
6+
import { resolveConstructorOptions } from '../instance/init'
67
import { activeInstance, callHook } from '../instance/lifecycle'
78
import { resolveSlots } from '../instance/render'
89
import { createElement } from './create-element'
@@ -33,6 +34,10 @@ export function createComponent (
3334
return
3435
}
3536

37+
// resolve constructor options in case global mixins are applied after
38+
// component constructor creation
39+
resolveConstructorOptions(Ctor)
40+
3641
// async component
3742
if (!Ctor.cid) {
3843
if (Ctor.resolved) {

test/unit/features/global-api/mixin.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,23 @@ describe('Global API: mixin', () => {
3737
})
3838
expect(calls).toEqual(['hello global', 'hello local'])
3939
})
40+
41+
// #3957
42+
it('should work for global props', () => {
43+
const Test = Vue.extend({
44+
template: `<div>{{ prop }}</div>`
45+
})
46+
47+
Vue.mixin({
48+
props: ['prop']
49+
})
50+
51+
// test child component
52+
const vm = new Vue({
53+
template: '<test prop="hi"></test>',
54+
components: { Test }
55+
}).$mount()
56+
57+
expect(vm.$el.textContent).toBe('hi')
58+
})
4059
})

0 commit comments

Comments
 (0)