feat(runtime-core): support using inject() inside props default functions

This commit is contained in:
Evan You 2020-09-17 15:59:01 -04:00
parent 985bd2bcb5
commit 58c31e3699
2 changed files with 46 additions and 10 deletions

View File

@ -8,7 +8,9 @@ import {
defineComponent, defineComponent,
ref, ref,
serializeInner, serializeInner,
createApp createApp,
provide,
inject
} from '@vue/runtime-test' } from '@vue/runtime-test'
import { render as domRender, nextTick } from 'vue' import { render as domRender, nextTick } from 'vue'
@ -212,6 +214,32 @@ describe('component props', () => {
expect(defaultFn).toHaveBeenCalledTimes(1) expect(defaultFn).toHaveBeenCalledTimes(1)
}) })
test('using inject in default value factory', () => {
const Child = defineComponent({
props: {
test: {
default: () => inject('test', 'default')
}
},
setup(props) {
return () => {
return h('div', props.test)
}
}
})
const Comp = {
setup() {
provide('test', 'injected')
return () => h(Child)
}
}
const root = nodeOps.createElement('div')
render(h(Comp), root)
expect(serializeInner(root)).toBe(`<div>injected</div>`)
})
test('optimized props updates', async () => { test('optimized props updates', async () => {
const Child = defineComponent({ const Child = defineComponent({
props: ['foo'], props: ['foo'],

View File

@ -27,7 +27,8 @@ import {
Data, Data,
ComponentInternalInstance, ComponentInternalInstance,
ComponentOptions, ComponentOptions,
ConcreteComponent ConcreteComponent,
setCurrentInstance
} from './component' } from './component'
import { isEmitListener } from './componentEmits' import { isEmitListener } from './componentEmits'
import { InternalObjectKey } from './vnode' import { InternalObjectKey } from './vnode'
@ -179,7 +180,8 @@ export function updateProps(
options, options,
rawCurrentProps, rawCurrentProps,
camelizedKey, camelizedKey,
value value,
instance
) )
} }
} else { } else {
@ -214,7 +216,8 @@ export function updateProps(
options, options,
rawProps || EMPTY_OBJ, rawProps || EMPTY_OBJ,
key, key,
undefined undefined,
instance
) )
} }
} else { } else {
@ -277,7 +280,8 @@ function setFullProps(
options!, options!,
rawCurrentProps, rawCurrentProps,
key, key,
rawCurrentProps[key] rawCurrentProps[key],
instance
) )
} }
} }
@ -287,7 +291,8 @@ function resolvePropValue(
options: NormalizedProps, options: NormalizedProps,
props: Data, props: Data,
key: string, key: string,
value: unknown value: unknown,
instance: ComponentInternalInstance
) { ) {
const opt = options[key] const opt = options[key]
if (opt != null) { if (opt != null) {
@ -295,10 +300,13 @@ function resolvePropValue(
// default values // default values
if (hasDefault && value === undefined) { if (hasDefault && value === undefined) {
const defaultValue = opt.default const defaultValue = opt.default
value = if (opt.type !== Function && isFunction(defaultValue)) {
opt.type !== Function && isFunction(defaultValue) setCurrentInstance(instance)
? defaultValue(props) value = defaultValue(props)
: defaultValue setCurrentInstance(null)
} else {
value = defaultValue
}
} }
// boolean casting // boolean casting
if (opt[BooleanFlags.shouldCast]) { if (opt[BooleanFlags.shouldCast]) {