mirror of https://github.com/vuejs/core.git
Merge 038dc1eefe
into ba391f5fdf
This commit is contained in:
commit
93f67546a7
|
@ -101,13 +101,14 @@ exports[`sfc reactive props destructure > default values w/ runtime declaration
|
||||||
"import { mergeDefaults as _mergeDefaults } from 'vue'
|
"import { mergeDefaults as _mergeDefaults } from 'vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: /*@__PURE__*/_mergeDefaults(['foo', 'foo:bar'], {
|
props: /*@__PURE__*/_mergeDefaults(['foo', 'foo:bar', 'baz'], {
|
||||||
foo: 1,
|
foo: 1,
|
||||||
"foo:bar": 'foo-bar'
|
"foo:bar": 'foo-bar',
|
||||||
|
baz: (props) => (props["foo"])
|
||||||
}),
|
}),
|
||||||
setup(__props) {
|
setup(__props) {
|
||||||
|
|
||||||
|
__props.foo
|
||||||
|
|
||||||
return () => {}
|
return () => {}
|
||||||
}
|
}
|
||||||
|
@ -142,11 +143,12 @@ export default /*@__PURE__*/_defineComponent({
|
||||||
props: {
|
props: {
|
||||||
foo: { type: Number, required: false, default: 1 },
|
foo: { type: Number, required: false, default: 1 },
|
||||||
bar: { type: Object, required: false, default: () => ({}) },
|
bar: { type: Object, required: false, default: () => ({}) },
|
||||||
func: { type: Function, required: false, default: () => {} }
|
func: { type: Function, required: false, default: () => {} },
|
||||||
|
baz: { type: Object, required: false, default: (props) => (props["bar"]) }
|
||||||
},
|
},
|
||||||
setup(__props: any) {
|
setup(__props: any) {
|
||||||
|
|
||||||
|
__props.bar
|
||||||
|
|
||||||
return () => {}
|
return () => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,25 +106,28 @@ describe('sfc reactive props destructure', () => {
|
||||||
})`)
|
})`)
|
||||||
assertCode(content)
|
assertCode(content)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('default values w/ runtime declaration & key is string', () => {
|
test('default values w/ runtime declaration & key is string', () => {
|
||||||
const { content, bindings } = compile(`
|
const { content, bindings } = compile(`
|
||||||
<script setup>
|
<script setup>
|
||||||
const { foo = 1, 'foo:bar': fooBar = 'foo-bar' } = defineProps(['foo', 'foo:bar'])
|
const { foo = 1, 'foo:bar': fooBar = 'foo-bar', baz = foo } = defineProps(['foo', 'foo:bar', 'baz'])
|
||||||
</script>
|
</script>
|
||||||
`)
|
`)
|
||||||
expect(bindings).toStrictEqual({
|
expect(bindings).toStrictEqual({
|
||||||
__propsAliases: {
|
__propsAliases: {
|
||||||
fooBar: 'foo:bar',
|
fooBar: 'foo:bar',
|
||||||
},
|
},
|
||||||
|
baz: BindingTypes.PROPS,
|
||||||
foo: BindingTypes.PROPS,
|
foo: BindingTypes.PROPS,
|
||||||
'foo:bar': BindingTypes.PROPS,
|
'foo:bar': BindingTypes.PROPS,
|
||||||
fooBar: BindingTypes.PROPS_ALIASED,
|
fooBar: BindingTypes.PROPS_ALIASED,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(content).toMatch(`
|
expect(content).toMatch(`
|
||||||
props: /*@__PURE__*/_mergeDefaults(['foo', 'foo:bar'], {
|
props: /*@__PURE__*/_mergeDefaults(['foo', 'foo:bar', 'baz'], {
|
||||||
foo: 1,
|
foo: 1,
|
||||||
"foo:bar": 'foo-bar'
|
"foo:bar": 'foo-bar',
|
||||||
|
baz: (props) => (props["foo"])
|
||||||
}),`)
|
}),`)
|
||||||
assertCode(content)
|
assertCode(content)
|
||||||
})
|
})
|
||||||
|
@ -132,7 +135,7 @@ describe('sfc reactive props destructure', () => {
|
||||||
test('default values w/ type declaration', () => {
|
test('default values w/ type declaration', () => {
|
||||||
const { content } = compile(`
|
const { content } = compile(`
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { foo = 1, bar = {}, func = () => {} } = defineProps<{ foo?: number, bar?: object, func?: () => any }>()
|
const { foo = 1, bar = {}, func = () => {}, baz = bar } = defineProps<{ foo?: number, bar?: object, func?: () => any, baz?: object }>()
|
||||||
</script>
|
</script>
|
||||||
`)
|
`)
|
||||||
// literals can be used as-is, non-literals are always returned from a
|
// literals can be used as-is, non-literals are always returned from a
|
||||||
|
@ -140,7 +143,8 @@ describe('sfc reactive props destructure', () => {
|
||||||
expect(content).toMatch(`props: {
|
expect(content).toMatch(`props: {
|
||||||
foo: { type: Number, required: false, default: 1 },
|
foo: { type: Number, required: false, default: 1 },
|
||||||
bar: { type: Object, required: false, default: () => ({}) },
|
bar: { type: Object, required: false, default: () => ({}) },
|
||||||
func: { type: Function, required: false, default: () => {} }
|
func: { type: Function, required: false, default: () => {} },
|
||||||
|
baz: { type: Object, required: false, default: (props) => (props["bar"]) }
|
||||||
}`)
|
}`)
|
||||||
assertCode(content)
|
assertCode(content)
|
||||||
})
|
})
|
||||||
|
|
|
@ -349,13 +349,16 @@ function genDestructuredDefaultValue(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDestructuredBinding = ctx.propsDestructuredBindings[value]
|
||||||
|
|
||||||
// If the default value is a function or is an identifier referencing
|
// If the default value is a function or is an identifier referencing
|
||||||
// external value, skip factory wrap. This is needed when using
|
// external value, skip factory wrap. This is needed when using
|
||||||
// destructure w/ runtime declaration since we cannot safely infer
|
// destructure w/ runtime declaration since we cannot safely infer
|
||||||
// whether the expected runtime prop type is `Function`.
|
// whether the expected runtime prop type is `Function`.
|
||||||
const needSkipFactory =
|
const needSkipFactory =
|
||||||
!inferredType &&
|
!inferredType &&
|
||||||
(isFunctionType(unwrapped) || unwrapped.type === 'Identifier')
|
(isFunctionType(unwrapped) ||
|
||||||
|
(unwrapped.type === 'Identifier' && !isDestructuredBinding))
|
||||||
|
|
||||||
const needFactoryWrap =
|
const needFactoryWrap =
|
||||||
!needSkipFactory &&
|
!needSkipFactory &&
|
||||||
|
@ -363,13 +366,17 @@ function genDestructuredDefaultValue(
|
||||||
!inferredType?.includes('Function')
|
!inferredType?.includes('Function')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valueString: needFactoryWrap ? `() => (${value})` : value,
|
valueString: needFactoryWrap
|
||||||
|
? isDestructuredBinding
|
||||||
|
? `(props) => (props["${value}"])`
|
||||||
|
: `() => (${value})`
|
||||||
|
: value,
|
||||||
needSkipFactory,
|
needSkipFactory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-comprehensive, best-effort type infernece for a runtime value
|
// non-comprehensive, best-effort type inference for a runtime value
|
||||||
// this is used to catch default value / type declaration mismatches
|
// this is used to catch default value / type declaration mismatches
|
||||||
// when using props destructure.
|
// when using props destructure.
|
||||||
function inferValueType(node: Node): string | undefined {
|
function inferValueType(node: Node): string | undefined {
|
||||||
|
|
Loading…
Reference in New Issue