Merge 87519fa279
into 5f8314cb7f
This commit is contained in:
commit
f1a3a77a22
|
@ -463,6 +463,27 @@ return { props, get defaults() { return defaults } }
|
|||
})"
|
||||
`;
|
||||
|
||||
exports[`defineProps > withDefaults (locally variable) 1`] = `
|
||||
"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
|
||||
const defaults = { baz: false }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: _mergeDefaults({
|
||||
baz: { type: Boolean, required: true }
|
||||
}, defaults),
|
||||
setup(__props: any, { expose: __expose }) {
|
||||
__expose();
|
||||
|
||||
const props = __props;
|
||||
|
||||
|
||||
|
||||
return { defaults, props }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`defineProps > withDefaults (reference) 1`] = `
|
||||
"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
|
||||
import { defaults } from './foo'
|
||||
|
|
|
@ -518,6 +518,26 @@ const props = defineProps({ foo: String })
|
|||
)
|
||||
})
|
||||
|
||||
test('withDefaults (locally variable)', () => {
|
||||
const { content } = compile(`
|
||||
<script setup lang="ts">
|
||||
const defaults = { baz: false }
|
||||
const props = withDefaults(defineProps<{
|
||||
baz: boolean
|
||||
}>(), defaults)
|
||||
</script>
|
||||
`)
|
||||
|
||||
assertCode(content)
|
||||
expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
|
||||
expect(content).toMatch(
|
||||
`
|
||||
_mergeDefaults({
|
||||
baz: { type: Boolean, required: true }
|
||||
}, defaults)`.trim()
|
||||
)
|
||||
})
|
||||
|
||||
// #7111
|
||||
test('withDefaults (dynamic) w/ production mode', () => {
|
||||
const { content } = compile(
|
||||
|
@ -677,6 +697,20 @@ const props = defineProps({ foo: String })
|
|||
</script>`)
|
||||
}).toThrow(`cannot accept both type and non-type arguments`)
|
||||
})
|
||||
|
||||
test('withDefaults (locally variable)', () => {
|
||||
expect(() => {
|
||||
compile(`
|
||||
<script setup lang="ts">
|
||||
const defaults = { bar: 1 }
|
||||
withDefaults(defineProps<{
|
||||
bar?: number
|
||||
}>(), defaults)
|
||||
defaults.bar++
|
||||
</script>
|
||||
`)
|
||||
}).toThrow(`cannot reference locally declared variables`)
|
||||
})
|
||||
})
|
||||
|
||||
test('should escape names w/ special symbols', () => {
|
||||
|
|
|
@ -198,6 +198,13 @@ export function compileScript(
|
|||
// const ctx.bindingMetadata: BindingMetadata = {}
|
||||
const scriptBindings: Record<string, BindingTypes> = Object.create(null)
|
||||
const setupBindings: Record<string, BindingTypes> = Object.create(null)
|
||||
const withDefaultsVariables: Record<
|
||||
string,
|
||||
{
|
||||
node: Statement
|
||||
needHoist?: boolean
|
||||
}
|
||||
> = {}
|
||||
|
||||
let defaultExport: Node | undefined
|
||||
let hasAwait = false
|
||||
|
@ -263,7 +270,11 @@ export function compileScript(
|
|||
if (!node) return
|
||||
walkIdentifiers(node, id => {
|
||||
const binding = setupBindings[id.name]
|
||||
if (binding && binding !== BindingTypes.LITERAL_CONST) {
|
||||
if (
|
||||
binding &&
|
||||
binding !== BindingTypes.LITERAL_CONST &&
|
||||
!withDefaultsVariables[id.name].needHoist
|
||||
) {
|
||||
ctx.error(
|
||||
`\`${method}()\` in <script setup> cannot reference locally ` +
|
||||
`declared variables because it will be hoisted outside of the ` +
|
||||
|
@ -648,6 +659,30 @@ export function compileScript(
|
|||
parent!.type === 'ExpressionStatement',
|
||||
)
|
||||
}
|
||||
|
||||
if (child.type === 'Identifier') {
|
||||
if (parent!.type === 'VariableDeclarator') {
|
||||
withDefaultsVariables[child.name] = {
|
||||
node
|
||||
}
|
||||
} else if (
|
||||
parent!.type === 'CallExpression' &&
|
||||
parent.callee.type === 'Identifier' &&
|
||||
parent.callee.name === WITH_DEFAULTS &&
|
||||
withDefaultsVariables[child.name]
|
||||
) {
|
||||
const variable = withDefaultsVariables[child.name]
|
||||
if (variable.needHoist !== false) {
|
||||
variable.needHoist = true
|
||||
}
|
||||
} else if (
|
||||
parent!.type !== 'VariableDeclaration' &&
|
||||
withDefaultsVariables[child.name]
|
||||
) {
|
||||
const variable = withDefaultsVariables[child.name]
|
||||
variable.needHoist = false
|
||||
}
|
||||
}
|
||||
},
|
||||
exit(node: Node) {
|
||||
if (node.type === 'BlockStatement') scope.pop()
|
||||
|
@ -683,6 +718,13 @@ export function compileScript(
|
|||
}
|
||||
}
|
||||
|
||||
for (const key in withDefaultsVariables) {
|
||||
const variable = withDefaultsVariables[key]
|
||||
if (variable.needHoist) {
|
||||
hoistNode(variable.node)
|
||||
}
|
||||
}
|
||||
|
||||
// 3 props destructure transform
|
||||
if (ctx.propsDestructureDecl) {
|
||||
transformDestructuredProps(ctx, vueImportAliases)
|
||||
|
|
Loading…
Reference in New Issue