Skip to content

Commit 258ff1e

Browse files
committed
refactor(compiler-vapor): cache inline handlers passed to component
1 parent ef6986f commit 258ff1e

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ exports[`compiler: element transform > component > should wrap as function if v-
100100
101101
export function render(_ctx) {
102102
const _component_Foo = _resolveComponent("Foo")
103-
const n0 = _createComponentWithFallback(_component_Foo, { onBar: () => $event => (_ctx.handleBar($event)) }, null, true)
103+
const _on_bar = $event => (_ctx.handleBar($event))
104+
const n0 = _createComponentWithFallback(_component_Foo, { onBar: () => _on_bar }, null, true)
104105
return n0
105106
}"
106107
`;

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,10 @@ describe('compiler: element transform', () => {
388388
`<Foo v-on:bar="handleBar($event)" />`,
389389
)
390390
expect(code).toMatchSnapshot()
391-
expect(code).contains(`onBar: () => $event => (_ctx.handleBar($event))`)
391+
expect(code).contains(
392+
`const _on_bar = $event => (_ctx.handleBar($event))`,
393+
)
394+
expect(code).contains(`onBar: () => _on_bar`)
392395
expect(ir.block.operation).toMatchObject([
393396
{
394397
type: IRNodeTypes.CREATE_COMPONENT_NODE,
@@ -398,7 +401,7 @@ describe('compiler: element transform', () => {
398401
{
399402
key: { content: 'bar' },
400403
handler: true,
401-
values: [{ content: 'handleBar($event)' }],
404+
values: [{ content: '_on_bar' }],
402405
},
403406
],
404407
],

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

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ import {
2929
import { genExpression } from './expression'
3030
import { genPropKey, genPropValue } from './prop'
3131
import {
32+
type SimpleExpressionNode,
3233
createSimpleExpression,
34+
isMemberExpression,
3335
toValidAssetId,
3436
walkIdentifiers,
3537
} from '@vue/compiler-core'
@@ -46,11 +48,20 @@ export function genCreateComponent(
4648

4749
const tag = genTag()
4850
const { root, props, slots, once } = operation
49-
const rawProps = genRawProps(props, context)
5051
const rawSlots = genRawSlots(slots, context)
52+
const [ids, handlers] = processInlineHandlers(props, context)
53+
const rawProps = context.withId(() => genRawProps(props, context), ids)
54+
const inlineHandlers: CodeFragment[] = handlers.reduce<CodeFragment[]>(
55+
(acc, { name, value }) => {
56+
const handler = genEventHandler(context, value, false)
57+
return [...acc, `const ${name} = `, ...handler, NEWLINE]
58+
},
59+
[],
60+
)
5161

5262
return [
5363
NEWLINE,
64+
...inlineHandlers,
5465
`const n${operation.id} = `,
5566
...genCall(
5667
operation.asset
@@ -82,6 +93,38 @@ export function genCreateComponent(
8293
}
8394
}
8495

96+
type InlineHandlerValue = {
97+
name: string
98+
value: SimpleExpressionNode
99+
}
100+
101+
function processInlineHandlers(
102+
props: IRProps[],
103+
context: CodegenContext,
104+
): [Record<string, null>, InlineHandlerValue[]] {
105+
const ids: Record<string, null> = Object.create(null)
106+
const handlers: InlineHandlerValue[] = []
107+
const staticProps = props[0]
108+
if (isArray(staticProps)) {
109+
for (let i = 0; i < staticProps.length; i++) {
110+
const prop = staticProps[i]
111+
if (!prop.handler) continue
112+
prop.values.forEach((value, i) => {
113+
const isMemberExp = isMemberExpression(value, context.options)
114+
// cache inline handlers (fn expression or inline statement)
115+
if (!isMemberExp) {
116+
const name = `_on_${prop.key.content}`
117+
handlers.push({ name, value })
118+
ids[name] = null
119+
// replace the original prop value with the handler name
120+
prop.values[i] = extend({ ast: null }, createSimpleExpression(name))
121+
}
122+
})
123+
}
124+
}
125+
return [ids, handlers]
126+
}
127+
85128
export function genRawProps(
86129
props: IRProps[],
87130
context: CodegenContext,

0 commit comments

Comments
 (0)