Skip to content

Commit 69041a7

Browse files
committed
feat(vue-jsx-vapor): introduce useProps and useFullProps
1 parent 876eb28 commit 69041a7

File tree

10 files changed

+161
-87
lines changed

10 files changed

+161
-87
lines changed

packages/macros/src/core/babel-utils.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { walkAST } from '@vue-macros/common'
1+
import { walkAST, type MagicStringAST } from '@vue-macros/common'
22
// should only use types from @babel/types
33
// do not import runtime methods
44
import type {
5+
ArrowFunctionExpression,
56
BlockStatement,
67
ForInStatement,
78
ForOfStatement,
89
ForStatement,
910
Function,
11+
FunctionDeclaration,
12+
FunctionExpression,
1013
Identifier,
1114
JSXIdentifier,
1215
Node,
@@ -534,3 +537,55 @@ export function isStaticNode(node: Node): boolean {
534537
}
535538
return false
536539
}
540+
541+
export type FunctionalNode =
542+
| FunctionDeclaration
543+
| FunctionExpression
544+
| ArrowFunctionExpression
545+
546+
export function prependFunctionalNode(
547+
node: FunctionalNode,
548+
s: MagicStringAST,
549+
result: string,
550+
): void {
551+
const isBlockStatement = node.body.type === 'BlockStatement'
552+
const start = node.body.extra?.parenthesized
553+
? (node.body.extra.parenStart as number)
554+
: node.body.start!
555+
s.appendRight(
556+
start + (isBlockStatement ? 1 : 0),
557+
`${result};${!isBlockStatement ? 'return ' : ''}`,
558+
)
559+
if (!isBlockStatement) {
560+
s.appendLeft(start, '{')
561+
s.appendRight(node.end!, '}')
562+
}
563+
}
564+
565+
export function isFunctionalNode(node?: Node | null): node is FunctionalNode {
566+
return !!(
567+
node &&
568+
(node.type === 'ArrowFunctionExpression' ||
569+
node.type === 'FunctionDeclaration' ||
570+
node.type === 'FunctionExpression')
571+
)
572+
}
573+
574+
export function getParamsStart(node: FunctionalNode, code: string): number {
575+
return node.params[0]
576+
? node.params[0].start!
577+
: node.start! +
578+
(code.slice(node.start!, node.body.start!).match(/\(\s*\)/)?.index ||
579+
0) +
580+
1
581+
}
582+
583+
export function getDefaultValue(node: Node): Node {
584+
if (node.type === 'TSNonNullExpression') {
585+
return getDefaultValue(node.expression)
586+
}
587+
if (node.type === 'TSAsExpression') {
588+
return getDefaultValue(node.expression)
589+
}
590+
return node
591+
}

packages/macros/src/core/define-component/await.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
walkAST,
77
type MagicStringAST,
88
} from '@vue-macros/common'
9-
import type { FunctionalNode } from '..'
9+
import type { FunctionalNode } from '../babel-utils'
1010
import type { AwaitExpression, Node, Statement } from '@babel/types'
1111

1212
export function transformAwait(root: FunctionalNode, s: MagicStringAST): void {

packages/macros/src/core/define-component/index.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
import { importHelperFn, type MagicStringAST } from '@vue-macros/common'
2-
import { isFunctionalNode, type FunctionalNode, type Macros } from '..'
3-
import { walkIdentifiers } from '../babel-utils'
4-
import { getDefaultValue, restructure } from '../restructure'
1+
import {
2+
HELPER_PREFIX,
3+
importHelperFn,
4+
type MagicStringAST,
5+
} from '@vue-macros/common'
6+
import {
7+
getDefaultValue,
8+
isFunctionalNode,
9+
prependFunctionalNode,
10+
walkIdentifiers,
11+
type FunctionalNode,
12+
} from '../babel-utils'
13+
import { restructure } from '../restructure'
14+
import type { Macros } from '..'
515
import { transformAwait } from './await'
616
import { transformReturn } from './return'
717
import type { Node, ObjectExpression } from '@babel/types'
@@ -28,6 +38,22 @@ export function transformDefineComponent(
2838
if (root.params[0]) {
2939
if (root.params[0].type === 'Identifier') {
3040
getWalkedIds(root, propsName).forEach((id) => (props[id] = null))
41+
prependFunctionalNode(
42+
root,
43+
s,
44+
`const ${propsName} = ${importHelperFn(
45+
s,
46+
0,
47+
'useFullProps',
48+
undefined,
49+
'vue-jsx-vapor',
50+
)}()`,
51+
)
52+
s.overwrite(
53+
root.params[0].start!,
54+
root.params[0].end!,
55+
`${HELPER_PREFIX}props`,
56+
)
3157
} else if (root.params[0].type === 'ObjectPattern') {
3258
const restructuredProps = root.params[0]
3359
for (const prop of restructuredProps.properties) {

packages/macros/src/core/define-component/return.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isFunctionalNode, type FunctionalNode } from '..'
1+
import { isFunctionalNode, type FunctionalNode } from '../babel-utils'
22
import type { MagicStringAST } from '@vue-macros/common'
33

44
export function transformReturn(root: FunctionalNode, s: MagicStringAST): void {

packages/macros/src/core/define-expose.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ import type { CallExpression } from '@babel/types'
44
export function transformDefineExpose(
55
node: CallExpression,
66
s: MagicStringAST,
7-
version: number,
87
): void {
98
s.overwriteNode(node.callee, ';')
109
s.appendRight(
1110
node.arguments[0]?.start || node.end! - 1,
12-
version >= 3.6
13-
? `${importHelperFn(s, 0, 'currentInstance')}.exposed = `
14-
: `${importHelperFn(s, 0, 'getCurrentInstance')}().exposed = `,
11+
`${importHelperFn(s, 0, 'getCurrentInstance', undefined, 'vue-jsx-vapor')}().exposed = `,
1512
)
1613
}

packages/macros/src/core/define-style.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { walkAST, type MagicStringAST } from '@vue-macros/common'
22
import hash from 'hash-sum'
33
import { helperPrefix } from './helper'
4-
import {
5-
isFunctionalNode,
6-
type DefineStyle,
7-
type FunctionalNode,
8-
type Macros,
9-
} from '.'
4+
import type { FunctionalNode } from './babel-utils'
5+
import { isFunctionalNode, type DefineStyle, type Macros } from '.'
106
import type { Node } from '@babel/types'
117

128
export function transformDefineStyle(

packages/macros/src/core/index.ts

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,21 @@ import {
88
type CodeTransform,
99
} from '@vue-macros/common'
1010
import type { OptionsResolved } from '../options'
11+
import {
12+
getParamsStart,
13+
isFunctionalNode,
14+
type FunctionalNode,
15+
} from './babel-utils'
1116
import { transformDefineComponent } from './define-component'
1217
import { transformDefineExpose } from './define-expose'
1318
import { transformDefineModel } from './define-model'
1419
import { transformDefineSlots } from './define-slots'
1520
import { transformDefineStyle } from './define-style'
16-
import type {
17-
ArrowFunctionExpression,
18-
CallExpression,
19-
FunctionDeclaration,
20-
FunctionExpression,
21-
LVal,
22-
Node,
23-
Program,
24-
} from '@babel/types'
21+
import type { CallExpression, LVal, Node, Program } from '@babel/types'
2522

26-
export { restructure } from './restructure'
23+
export { isFunctionalNode }
2724

28-
export type FunctionalNode =
29-
| FunctionDeclaration
30-
| FunctionExpression
31-
| ArrowFunctionExpression
25+
export { restructure } from './restructure'
3226

3327
export type DefineStyle = {
3428
expression: CallExpression
@@ -123,7 +117,7 @@ export function transformJsxMacros(
123117
transformDefineSlots(macros.defineSlots.expression, s)
124118
}
125119
if (macros.defineExpose) {
126-
transformDefineExpose(macros.defineExpose, s, options.version)
120+
transformDefineExpose(macros.defineExpose, s)
127121
}
128122
}
129123

@@ -204,15 +198,6 @@ function getRootMap(ast: Program, s: MagicStringAST, options: OptionsResolved) {
204198
return rootMap
205199
}
206200

207-
export function isFunctionalNode(node?: Node | null): node is FunctionalNode {
208-
return !!(
209-
node &&
210-
(node.type === 'ArrowFunctionExpression' ||
211-
node.type === 'FunctionDeclaration' ||
212-
node.type === 'FunctionExpression')
213-
)
214-
}
215-
216201
export function getMacroExpression(
217202
node: Node,
218203
options: OptionsResolved,
@@ -242,12 +227,3 @@ export function getMacroExpression(
242227
}
243228
}
244229
}
245-
246-
export function getParamsStart(node: FunctionalNode, code: string): number {
247-
return node.params[0]
248-
? node.params[0].start!
249-
: node.start! +
250-
(code.slice(node.start!, node.body.start!).match(/\(\s*\)/)?.index ||
251-
0) +
252-
1
253-
}

packages/macros/src/core/restructure.ts

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import {
33
importHelperFn,
44
type MagicStringAST,
55
} from '@vue-macros/common'
6-
import { walkIdentifiers } from './babel-utils'
6+
import {
7+
getDefaultValue,
8+
prependFunctionalNode,
9+
walkIdentifiers,
10+
type FunctionalNode,
11+
} from './babel-utils'
712
import { withDefaultsHelperId } from './helper'
8-
import type { FunctionalNode } from '.'
913
import type { Node } from '@babel/types'
1014

1115
type Options = {
@@ -204,32 +208,3 @@ function getProps(
204208
})
205209
return props.length ? props : undefined
206210
}
207-
208-
export function getDefaultValue(node: Node): Node {
209-
if (node.type === 'TSNonNullExpression') {
210-
return getDefaultValue(node.expression)
211-
}
212-
if (node.type === 'TSAsExpression') {
213-
return getDefaultValue(node.expression)
214-
}
215-
return node
216-
}
217-
218-
function prependFunctionalNode(
219-
node: FunctionalNode,
220-
s: MagicStringAST,
221-
result: string,
222-
): void {
223-
const isBlockStatement = node.body.type === 'BlockStatement'
224-
const start = node.body.extra?.parenthesized
225-
? (node.body.extra.parenStart as number)
226-
: node.body.start!
227-
s.appendRight(
228-
start + (isBlockStatement ? 1 : 0),
229-
`${result};${!isBlockStatement ? 'return ' : ''}`,
230-
)
231-
if (!isBlockStatement) {
232-
s.appendLeft(start, '{')
233-
s.appendRight(node.end!, '}')
234-
}
235-
}

packages/macros/tests/__snapshots__/fixtures.spec.ts.snap

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ exports[`defineComponent autoReturnFunction fixtures > ./fixtures/define-compone
44
"
55
import { useAttrs as __MACROS_useAttrs } from "vue";
66
import { useModel as __MACROS_useModel } from "vue-jsx-vapor/macros/use-model";
7+
import { useFullProps as __MACROS_useFullProps } from "vue-jsx-vapor";
78
import { withAsyncContext as __MACROS_withAsyncContext } from "vue";import { defineComponent, nextTick, unref } from 'vue'
89
910
const $ = unref
@@ -38,7 +39,7 @@ const Comp = defineComponent(
3839
}, ...{ Comp: Object }} },
3940
)
4041
41-
const Comp1 = defineComponent((props: { bar: 'bar'; 'onUpdate:bar': any, comp: any }) => {
42+
const Comp1 = defineComponent((__MACROS_props) => {const props = __MACROS_useFullProps();
4243
const foo = __MACROS_useModel(props, 'foo')
4344
return () => <div>
4445
{[foo.value, props['bar'], props['onUpdate:bar']]}
@@ -104,6 +105,7 @@ exports[`fixtures > ./fixtures/define-component.tsx 1`] = `
104105
"
105106
import { useAttrs as __MACROS_useAttrs } from "vue";
106107
import { useModel as __MACROS_useModel } from "vue-jsx-vapor/macros/use-model";
108+
import { useFullProps as __MACROS_useFullProps } from "vue-jsx-vapor";
107109
import { withAsyncContext as __MACROS_withAsyncContext } from "vue";import { defineComponent, nextTick, unref } from 'vue'
108110
109111
const $ = unref
@@ -138,7 +140,7 @@ const Comp = defineComponent(
138140
}, ...{ Comp: Object }} },
139141
)
140142
141-
const Comp1 = defineComponent((props: { bar: 'bar'; 'onUpdate:bar': any, comp: any }) => {
143+
const Comp1 = defineComponent((__MACROS_props) => {const props = __MACROS_useFullProps();
142144
const foo = __MACROS_useModel(props, 'foo')
143145
return <div>
144146
{[foo.value, props['bar'], props['onUpdate:bar']]}
@@ -202,22 +204,22 @@ defineComponent((__MACROS_props) => {
202204

203205
exports[`fixtures > ./fixtures/define-expose.tsx 1`] = `
204206
"
205-
import { currentInstance as __MACROS_currentInstance } from "vue";export function Comp(__MACROS_props) {
206-
;(__MACROS_currentInstance.exposed = {
207+
import { getCurrentInstance as __MACROS_getCurrentInstance } from "vue-jsx-vapor";export function Comp(__MACROS_props) {
208+
;(__MACROS_getCurrentInstance().exposed = {
207209
foo: 1,
208210
})
209211
return <div />
210212
}
211213
212214
export const Comp1 = function (props: any) {
213-
;(__MACROS_currentInstance.exposed = {
215+
;(__MACROS_getCurrentInstance().exposed = {
214216
foo: props.foo,
215217
})
216218
return <div />
217219
}
218220
219221
export const Comp2 = ({ foo, ...__MACROS_props }: any) => {
220-
;(__MACROS_currentInstance.exposed = {
222+
;(__MACROS_getCurrentInstance().exposed = {
221223
foo,
222224
})
223225
return <div />

0 commit comments

Comments
 (0)