Skip to content

Commit b5fa188

Browse files
committed
feat(better-define): support dynamic default definitions
1 parent e1f7bdc commit b5fa188

File tree

12 files changed

+108
-17
lines changed

12 files changed

+108
-17
lines changed

.changeset/tidy-drinks-jump.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@vue-macros/api': patch
3+
'@vue-macros/better-define': patch
4+
'@vue-macros/common': patch
5+
---
6+
7+
support dynamic default definitions of props

packages/api/src/vue/props.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ export async function handleTSPropsDefinition({
307307
array: true,
308308
object: true,
309309
objectMethod: true,
310-
unary: true,
311310
})
312311
if (!isStatic) return { defaultsAst: defaultsAst as Expression }
313312

packages/api/tests/__snapshots__/analyzeSFC.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ exports[`analyzeSFC > defineProps > should resolve referenced type 1`] = `
581581
}
582582
`;
583583
584-
exports[`analyzeSFC > defineProps w/ withDefaults 1`] = `
584+
exports[`analyzeSFC > defineProps w/ withDefaults (static) 1`] = `
585585
{
586586
"bar": Node {
587587
"async": false,

packages/api/tests/analyzeSFC.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ describe('analyzeSFC', () => {
335335
})
336336
})
337337

338-
test('defineProps w/ withDefaults', async () => {
338+
test('defineProps w/ withDefaults (static)', async () => {
339339
const { props } = await complie(`withDefaults(defineProps<{
340340
foo: string
341341
bar?(): void
@@ -396,6 +396,18 @@ describe('analyzeSFC', () => {
396396

397397
snapshot(props!.defaults)
398398
})
399+
400+
test('defineProps w/ withDefaults (dynamic)', async () => {
401+
const { props } = await complie(`withDefaults(defineProps<{
402+
foo: string
403+
bar?: number
404+
}>(), {
405+
['b' + 'ar']: 'bar'
406+
})`)
407+
const defaults = await props!.getRuntimeDefinitions()
408+
expect(defaults.bar.default).toBeUndefined()
409+
expect(props!.defaults).toBeUndefined()
410+
})
399411
test.todo('mutate defaults')
400412

401413
describe('defineEmits', () => {

packages/better-define/src/core/index.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,24 @@ export const transformBetterDefine = async (code: string, id: string) => {
3535
})
3636
.join(',\n ')}\n}`
3737

38-
s.overwriteNode(
39-
props.withDefaultsAst || props.definePropsAst,
40-
`defineProps(${runtimeDecls})`,
41-
{
38+
let decl = runtimeDecls
39+
if (props.withDefaultsAst && !props.defaults) {
40+
// dynamic defaults
41+
decl = `_BD_mergeDefaults(${decl}, ${s.sliceNode(
42+
props.withDefaultsAst.arguments[1],
43+
{ offset }
44+
)})`
45+
// add helper
46+
s.prependLeft(
4247
offset,
43-
}
44-
)
48+
`import { mergeDefaults as _BD_mergeDefaults } from 'vue'`
49+
)
50+
}
51+
decl = `defineProps(${decl})`
52+
53+
s.overwriteNode(props.withDefaultsAst || props.definePropsAst, decl, {
54+
offset,
55+
})
4556
}
4657

4758
function processEmits(emits: TSEmits) {

packages/better-define/tests/__snapshots__/fixtures.test.ts.snap

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,42 @@ export { basic as default };
3535
"
3636
`;
3737

38-
exports[`fixtures > tests/fixtures/defaults.vue 1`] = `
38+
exports[`fixtures > tests/fixtures/defaults-dynamic.vue 1`] = `
39+
"import { defineComponent, mergeDefaults, openBlock, createElementBlock } from 'vue';
40+
41+
var _sfc_main = /* @__PURE__ */ defineComponent({
42+
__name: \\"defaults-dynamic\\",
43+
props: mergeDefaults({
44+
foo: { type: String, required: false }
45+
}, {
46+
[\\"foo\\"]: \\"foo\\"
47+
}),
48+
setup(__props) {
49+
return (_ctx, _cache) => {
50+
return openBlock(), createElementBlock(\\"div\\");
51+
};
52+
}
53+
});
54+
55+
var _export_sfc = (sfc, props) => {
56+
const target = sfc.__vccOpts || sfc;
57+
for (const [key, val] of props) {
58+
target[key] = val;
59+
}
60+
return target;
61+
};
62+
63+
var defaultsDynamic = /* @__PURE__ */ _export_sfc(_sfc_main, [__FILE__]);
64+
65+
export { defaultsDynamic as default };
66+
"
67+
`;
68+
69+
exports[`fixtures > tests/fixtures/defaults-static.vue 1`] = `
3970
"import { defineComponent, openBlock, createElementBlock } from 'vue';
4071
4172
var _sfc_main = /* @__PURE__ */ defineComponent({
42-
__name: \\"defaults\\",
73+
__name: \\"defaults-static\\",
4374
props: {
4475
foo: { type: String, required: false, default: \\"foo\\" },
4576
bar: { type: Number, required: false, get default() {
@@ -64,9 +95,9 @@ var _export_sfc = (sfc, props) => {
6495
return target;
6596
};
6697
67-
var defaults = /* @__PURE__ */ _export_sfc(_sfc_main, [__FILE__]);
98+
var defaultsStatic = /* @__PURE__ */ _export_sfc(_sfc_main, [__FILE__]);
6899
69-
export { defaults as default };
100+
export { defaultsStatic as default };
70101
"
71102
`;
72103

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
withDefaults(defineProps<{
3+
foo?: string
4+
5+
}>(), {
6+
['f' + 'oo']: 'foo'
7+
})
8+
</script>
9+
10+
<template>
11+
<div />
12+
</template>

packages/better-define/tests/fixtures/defaults.vue renamed to packages/better-define/tests/fixtures/defaults-static.vue

File renamed without changes.

packages/common/src/ast.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ export function isStaticExpression(
121121
case 'ArrayExpression': // [1, 2]
122122
return (
123123
!!array &&
124-
node.elements.every((element) => element && isStaticExpression(element))
124+
node.elements.every(
125+
(element) => element && isStaticExpression(element, options)
126+
)
125127
)
126128

127129
case 'ObjectExpression': // { foo: 1 }
@@ -133,11 +135,11 @@ export function isStaticExpression(
133135
prop.argument.type === 'ObjectExpression' &&
134136
isStaticExpression(prop.argument, options)
135137
)
136-
} else if (!isStaticExpression(prop.key) && prop.computed) {
138+
} else if (!isLiteralType(prop.key) && prop.computed) {
137139
return false
138140
} else if (
139141
prop.type === 'ObjectProperty' &&
140-
!isStaticExpression(prop.value)
142+
!isStaticExpression(prop.value, options)
141143
) {
142144
return false
143145
}

playground/vue3/src/examples/better-define/child.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ withDefaults(
1111
defineProps<
1212
Props & {
1313
union?: string | number
14+
nonStaticValue?: string
1415
}
1516
>(),
16-
{ union: 'defaultValue' }
17+
{
18+
...{ union: 'defaultValue' },
19+
['non' + 'StaticValue']: 'defaultValue',
20+
}
1721
)
1822
1923
defineEmits<Emits>()

0 commit comments

Comments
 (0)