Browse Source

fix global mixin props (fix #3957)

dev
Evan You 8 years ago
parent
commit
cb1bb75b58
  1. 55
      src/core/instance/init.js
  2. 5
      src/core/vdom/create-component.js
  3. 19
      test/unit/features/global-api/mixin.spec.js

55
src/core/instance/init.js

@ -24,7 +24,7 @@ export function initMixin (Vue: Class<Component>) {
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm),
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
@ -44,37 +44,36 @@ export function initMixin (Vue: Class<Component>) {
callHook(vm, 'created')
initRender(vm)
}
}
function initInternalComponent (vm: Component, options: InternalComponentOptions) {
const opts = vm.$options = Object.create(resolveConstructorOptions(vm))
// doing this because it's faster than dynamic enumeration.
opts.parent = options.parent
opts.propsData = options.propsData
opts._parentVnode = options._parentVnode
opts._parentListeners = options._parentListeners
opts._renderChildren = options._renderChildren
opts._componentTag = options._componentTag
if (options.render) {
opts.render = options.render
opts.staticRenderFns = options.staticRenderFns
}
function initInternalComponent (vm: Component, options: InternalComponentOptions) {
const opts = vm.$options = Object.create(vm.constructor.options)
// doing this because it's faster than dynamic enumeration.
opts.parent = options.parent
opts.propsData = options.propsData
opts._parentVnode = options._parentVnode
opts._parentListeners = options._parentListeners
opts._renderChildren = options._renderChildren
opts._componentTag = options._componentTag
if (options.render) {
opts.render = options.render
opts.staticRenderFns = options.staticRenderFns
}
}
function resolveConstructorOptions (vm: Component) {
const Ctor = vm.constructor
let options = Ctor.options
if (Ctor.super) {
const superOptions = Ctor.super.options
const cachedSuperOptions = Ctor.superOptions
if (superOptions !== cachedSuperOptions) {
// super option changed
Ctor.superOptions = superOptions
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
if (options.name) {
options.components[options.name] = Ctor
}
export function resolveConstructorOptions (Ctor: Class<Component>) {
let options = Ctor.options
if (Ctor.super) {
const superOptions = Ctor.super.options
const cachedSuperOptions = Ctor.superOptions
if (superOptions !== cachedSuperOptions) {
// super option changed
Ctor.superOptions = superOptions
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
if (options.name) {
options.components[options.name] = Ctor
}
}
return options
}
return options
}

5
src/core/vdom/create-component.js

@ -3,6 +3,7 @@
import Vue from '../instance/index'
import VNode from './vnode'
import { normalizeChildren } from './helpers/index'
import { resolveConstructorOptions } from '../instance/init'
import { activeInstance, callHook } from '../instance/lifecycle'
import { resolveSlots } from '../instance/render'
import { createElement } from './create-element'
@ -33,6 +34,10 @@ export function createComponent (
return
}
// resolve constructor options in case global mixins are applied after
// component constructor creation
resolveConstructorOptions(Ctor)
// async component
if (!Ctor.cid) {
if (Ctor.resolved) {

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

@ -37,4 +37,23 @@ describe('Global API: mixin', () => {
})
expect(calls).toEqual(['hello global', 'hello local'])
})
// #3957
it('should work for global props', () => {
const Test = Vue.extend({
template: `<div>{{ prop }}</div>`
})
Vue.mixin({
props: ['prop']
})
// test child component
const vm = new Vue({
template: '<test prop="hi"></test>',
components: { Test }
}).$mount()
expect(vm.$el.textContent).toBe('hi')
})
})

Loading…
Cancel
Save