Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit e2b51d6

Browse files
committed
feat(compiler-vapor): resolve directive
1 parent 30f9894 commit e2b51d6

File tree

11 files changed

+143
-115
lines changed

11 files changed

+143
-115
lines changed

packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,34 @@ exports[`compile > custom directive > basic 1`] = `
1616
const t0 = _template("<div></div>")
1717
1818
export function render(_ctx) {
19+
const _directive_test = _resolveDirective("test")
20+
const _directive_hello = _resolveDirective("hello")
1921
const n0 = t0()
20-
_withDirectives(n0, [[_resolveDirective("vTest")], [_resolveDirective("vHello"), void 0, void 0, { world: true }]])
22+
_withDirectives(n0, [[_directive_test], [_directive_hello, void 0, void 0, { world: true }]])
2123
return n0
2224
}"
2325
`;
2426

2527
exports[`compile > custom directive > component 1`] = `
26-
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, resolveDirective as _resolveDirective, withDirectives as _withDirectives, insert as _insert, createIf as _createIf, template as _template } from 'vue/vapor';
28+
"import { resolveComponent as _resolveComponent, resolveDirective as _resolveDirective, createComponent as _createComponent, withDirectives as _withDirectives, insert as _insert, createIf as _createIf, template as _template } from 'vue/vapor';
2729
const t0 = _template("<div></div>")
2830
2931
export function render(_ctx) {
3032
const _component_Bar = _resolveComponent("Bar")
3133
const _component_Comp = _resolveComponent("Comp")
34+
const _directive_hello = _resolveDirective("hello")
35+
const _directive_test = _resolveDirective("test")
3236
const n4 = _createComponent(_component_Comp, null, { default: () => {
3337
const n0 = _createIf(() => (true), () => {
3438
const n3 = t0()
3539
const n2 = _createComponent(_component_Bar)
36-
_withDirectives(n2, [[_resolveDirective("vHello"), void 0, void 0, { world: true }]])
40+
_withDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]])
3741
_insert(n2, n3)
3842
return n3
3943
})
4044
return n0
4145
} }, null, true)
42-
_withDirectives(n4, [[_resolveDirective("vTest")]])
46+
_withDirectives(n4, [[_directive_test]])
4347
return n4
4448
}"
4549
`;

packages/compiler-vapor/__tests__/transforms/__snapshots__/transformSlotOutlet.spec.ts.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ export function render(_ctx) {
7171
`;
7272
7373
exports[`compiler: transform <slot> outlets > error on unexpected custom directive on <slot> 1`] = `
74-
"import { createSlot as _createSlot } from 'vue/vapor';
74+
"import { resolveDirective as _resolveDirective, createSlot as _createSlot } from 'vue/vapor';
7575
7676
export function render(_ctx) {
77+
const _directive_foo = _resolveDirective("foo")
7778
const n0 = _createSlot("default", null)
7879
return n0
7980
}"

packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('compiler: element transform', () => {
3636
type: IRNodeTypes.CREATE_COMPONENT_NODE,
3737
id: 0,
3838
tag: 'Foo',
39-
resolve: true,
39+
asset: true,
4040
root: true,
4141
props: [[]],
4242
},
@@ -66,7 +66,7 @@ describe('compiler: element transform', () => {
6666
{
6767
type: IRNodeTypes.CREATE_COMPONENT_NODE,
6868
tag: 'Example',
69-
resolve: false,
69+
asset: false,
7070
},
7171
])
7272
})
@@ -172,7 +172,7 @@ describe('compiler: element transform', () => {
172172
type: IRNodeTypes.CREATE_COMPONENT_NODE,
173173
id: 0,
174174
tag: 'Example',
175-
resolve: true,
175+
asset: true,
176176
},
177177
])
178178
})
@@ -212,7 +212,7 @@ describe('compiler: element transform', () => {
212212
{
213213
type: IRNodeTypes.CREATE_COMPONENT_NODE,
214214
tag: 'Foo',
215-
resolve: true,
215+
asset: true,
216216
root: true,
217217
props: [
218218
[

packages/compiler-vapor/src/generators/block.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { BlockIRNode } from '../ir'
1+
import type { BlockIRNode, VaporHelper } from '../ir'
22
import {
33
type CodeFragment,
44
DELIMITERS_ARRAY,
@@ -12,6 +12,7 @@ import {
1212
import type { CodegenContext } from '../generate'
1313
import { genEffects, genOperations } from './operation'
1414
import { genChildren } from './template'
15+
import { toValidAssetId } from '@vue/compiler-dom'
1516

1617
export function genBlock(
1718
oper: BlockIRNode,
@@ -43,16 +44,8 @@ export function genBlockContent(
4344
const resetBlock = context.enterBlock(block)
4445

4546
if (root) {
46-
for (const name of context.ir.component) {
47-
push(
48-
NEWLINE,
49-
`const _component_${name} = `,
50-
...genCall(
51-
context.vaporHelper('resolveComponent'),
52-
JSON.stringify(name),
53-
),
54-
)
55-
}
47+
genResolveAssets('component', 'resolveComponent')
48+
genResolveAssets('directive', 'resolveDirective')
5649
}
5750

5851
for (const child of dynamic.children) {
@@ -77,4 +70,17 @@ export function genBlockContent(
7770

7871
resetBlock()
7972
return frag
73+
74+
function genResolveAssets(
75+
kind: 'component' | 'directive',
76+
helper: VaporHelper,
77+
) {
78+
for (const name of context.ir[kind]) {
79+
push(
80+
NEWLINE,
81+
`const ${toValidAssetId(name, kind)} = `,
82+
...genCall(context.vaporHelper(helper), JSON.stringify(name)),
83+
)
84+
}
85+
}
8086
}

packages/compiler-vapor/src/generators/component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
} from './utils'
2222
import { genExpression } from './expression'
2323
import { genPropKey } from './prop'
24-
import { createSimpleExpression } from '@vue/compiler-dom'
24+
import { createSimpleExpression, toValidAssetId } from '@vue/compiler-dom'
2525
import { genEventHandler } from './event'
2626
import { genDirectiveModifiers, genDirectivesForElement } from './directive'
2727
import { genModelHandler } from './modelValue'
@@ -52,8 +52,8 @@ export function genCreateComponent(
5252
]
5353

5454
function genTag() {
55-
if (oper.resolve) {
56-
return [`_component_${oper.tag}`]
55+
if (oper.asset) {
56+
return toValidAssetId(oper.tag, 'component')
5757
} else {
5858
return genExpression(
5959
extend(createSimpleExpression(oper.tag, false), { ast: null }),

packages/compiler-vapor/src/generators/directive.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { createSimpleExpression, isSimpleIdentifier } from '@vue/compiler-dom'
2-
import { camelize } from '@vue/shared'
1+
import {
2+
createSimpleExpression,
3+
isSimpleIdentifier,
4+
toValidAssetId,
5+
} from '@vue/compiler-dom'
6+
import { extend } from '@vue/shared'
37
import { genExpression } from './expression'
48
import type { CodegenContext } from '../generate'
59
import {
@@ -36,7 +40,12 @@ export function genWithDirective(
3640
...genCall(vaporHelper('withDirectives'), element, directives),
3741
]
3842

39-
function genDirective({ dir, builtin }: WithDirectiveIRNode): CodeFragment[] {
43+
function genDirective({
44+
dir,
45+
name,
46+
builtin,
47+
asset,
48+
}: WithDirectiveIRNode): CodeFragment[] {
4049
const directive = genDirective()
4150
const value = dir.exp && ['() => ', ...genExpression(dir.exp, context)]
4251
const argument = dir.arg && genExpression(dir.arg, context)
@@ -55,24 +64,15 @@ export function genWithDirective(
5564
)
5665

5766
function genDirective() {
58-
const {
59-
vaporHelper,
60-
options: { bindingMetadata },
61-
} = context
62-
if (dir.name === 'show') {
63-
return [vaporHelper('vShow')]
64-
} else if (builtin) {
65-
return [vaporHelper(builtin)]
67+
if (builtin) {
68+
return vaporHelper(name as any)
69+
} else if (asset) {
70+
return toValidAssetId(name, 'directive')
6671
} else {
67-
const directiveReference = camelize(`v-${dir.name}`)
68-
// TODO resolve directive
69-
if (bindingMetadata[directiveReference]) {
70-
const directiveExpression = createSimpleExpression(directiveReference)
71-
directiveExpression.ast = null
72-
return genExpression(directiveExpression, context)
73-
} else {
74-
return `${vaporHelper('resolveDirective')}("${directiveReference}")`
75-
}
72+
return genExpression(
73+
extend(createSimpleExpression(name, false), { ast: null }),
74+
context,
75+
)
7676
}
7777
}
7878
}

packages/compiler-vapor/src/ir.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface RootIRNode {
6060
source: string
6161
template: string[]
6262
component: Set<string>
63+
directive: Set<string>
6364
block: BlockIRNode
6465
}
6566

@@ -197,7 +198,9 @@ export interface WithDirectiveIRNode extends BaseIRNode {
197198
type: IRNodeTypes.WITH_DIRECTIVE
198199
element: number
199200
dir: VaporDirectiveNode
200-
builtin?: VaporHelper
201+
name: string
202+
builtin?: boolean
203+
asset?: boolean
201204
}
202205

203206
export interface ComponentSlotBlockIRNode extends BlockIRNode {
@@ -219,7 +222,7 @@ export interface CreateComponentIRNode extends BaseIRNode {
219222
slots?: ComponentSlots
220223
dynamicSlots?: ComponentDynamicSlot[]
221224

222-
resolve: boolean
225+
asset: boolean
223226
root: boolean
224227
}
225228

packages/compiler-vapor/src/transform.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ export class TransformContext<T extends AllNode = AllNode> {
7979

8080
comment: CommentNode[] = []
8181
component: Set<string> = this.ir.component
82+
directive: Set<string> = this.ir.directive
83+
8284
slots?: ComponentSlots
8385
dynamicSlots?: ComponentDynamicSlot[]
8486

@@ -220,6 +222,7 @@ export function transform(
220222
source: node.source,
221223
template: [],
222224
component: new Set(),
225+
directive: new Set(),
223226
block: newBlock(node),
224227
}
225228

packages/compiler-vapor/src/transforms/transformElement.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,24 @@ function transformComponentElement(
7272
propsResult: PropsResult,
7373
context: TransformContext,
7474
) {
75-
let resolve = true
75+
let asset = true
7676

7777
if (!__BROWSER__) {
7878
const fromSetup = resolveSetupReference(tag, context)
7979
if (fromSetup) {
8080
tag = fromSetup
81-
resolve = false
81+
asset = false
8282
}
8383
const dotIndex = tag.indexOf('.')
8484
if (dotIndex > 0) {
8585
const ns = resolveSetupReference(tag.slice(0, dotIndex), context)
8686
if (ns) {
8787
tag = ns + tag.slice(dotIndex)
88-
resolve = false
88+
asset = false
8989
}
9090
}
9191
}
92-
if (resolve) {
92+
if (asset) {
9393
context.component.add(tag)
9494
}
9595

@@ -102,7 +102,7 @@ function transformComponentElement(
102102
id: context.reference(),
103103
tag,
104104
props: propsResult[0] ? propsResult[1] : [propsResult[1]],
105-
resolve,
105+
asset,
106106
root,
107107
slots: context.slots,
108108
dynamicSlots: context.dynamicSlots,
@@ -287,7 +287,7 @@ function transformProp(
287287
node: ElementNode,
288288
context: TransformContext<ElementNode>,
289289
): DirectiveTransformResult | void {
290-
const { name } = prop
290+
let { name } = prop
291291

292292
if (prop.type === NodeTypes.ATTRIBUTE) {
293293
if (isReservedProp(name)) return
@@ -305,10 +305,20 @@ function transformProp(
305305
}
306306

307307
if (!isBuiltInDirective(name)) {
308+
const fromSetup =
309+
!__BROWSER__ && resolveSetupReference(`v-${name}`, context)
310+
if (fromSetup) {
311+
name = fromSetup
312+
} else {
313+
context.directive.add(name)
314+
}
315+
308316
context.registerOperation({
309317
type: IRNodeTypes.WITH_DIRECTIVE,
310318
element: context.reference(),
311319
dir: prop,
320+
name,
321+
asset: !fromSetup,
312322
})
313323
}
314324
}

0 commit comments

Comments
 (0)