Skip to content

Commit f6e71af

Browse files
committed
Merge branch 'main' of https://github.com/vuejs/core-vapor into feat/component-emits
2 parents 26c958d + 69b8074 commit f6e71af

File tree

12 files changed

+136
-73
lines changed

12 files changed

+136
-73
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ PR are welcome!
2929
- [x] `v-bind`
3030
- [x] simple expression
3131
- [x] compound expression
32-
- [ ] modifiers
32+
- [x] modifiers
3333
- [x] .camel
34-
- [ ] .prop
35-
- [ ] .attr
34+
- [x] .prop
35+
- [x] .attr
3636
- [x] `v-on`
3737
- [x] simple expression
3838
- [x] compound expression

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`compiler v-bind > .attr modifier 1`] = `
4-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
4+
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
55
66
export function render(_ctx) {
77
const t0 = _template("<div></div>")
88
const n0 = t0()
99
const { 0: [n1],} = _children(n0)
1010
_renderEffect(() => {
11-
_setDynamicProp(n1, "^foo-bar", undefined, _ctx.id)
11+
_setAttr(n1, "foo-bar", undefined, _ctx.id)
1212
})
1313
return n0
1414
}"
1515
`;
1616

1717
exports[`compiler v-bind > .attr modifier w/ no expression 1`] = `
18-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
18+
"import { template as _template, children as _children, renderEffect as _renderEffect, setAttr as _setAttr } from 'vue/vapor';
1919
2020
export function render(_ctx) {
2121
const t0 = _template("<div></div>")
2222
const n0 = t0()
2323
const { 0: [n1],} = _children(n0)
2424
_renderEffect(() => {
25-
_setDynamicProp(n1, "^foo-bar", undefined, _ctx.fooBar)
25+
_setAttr(n1, "foo-bar", undefined, _ctx.fooBar)
2626
})
2727
return n0
2828
}"
@@ -71,42 +71,42 @@ export function render(_ctx) {
7171
`;
7272

7373
exports[`compiler v-bind > .prop modifier (shortband) w/ no expression 1`] = `
74-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
74+
"import { template as _template, children as _children, renderEffect as _renderEffect, setDOMProp as _setDOMProp } from 'vue/vapor';
7575
7676
export function render(_ctx) {
7777
const t0 = _template("<div></div>")
7878
const n0 = t0()
7979
const { 0: [n1],} = _children(n0)
8080
_renderEffect(() => {
81-
_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)
81+
_setDOMProp(n1, "fooBar", undefined, _ctx.fooBar)
8282
})
8383
return n0
8484
}"
8585
`;
8686

8787
exports[`compiler v-bind > .prop modifier (shorthand) 1`] = `
88-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
88+
"import { template as _template, children as _children, renderEffect as _renderEffect, setDOMProp as _setDOMProp } from 'vue/vapor';
8989
9090
export function render(_ctx) {
9191
const t0 = _template("<div></div>")
9292
const n0 = t0()
9393
const { 0: [n1],} = _children(n0)
9494
_renderEffect(() => {
95-
_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)
95+
_setDOMProp(n1, "fooBar", undefined, _ctx.id)
9696
})
9797
return n0
9898
}"
9999
`;
100100

101101
exports[`compiler v-bind > .prop modifier 1`] = `
102-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
102+
"import { template as _template, children as _children, renderEffect as _renderEffect, setDOMProp as _setDOMProp } from 'vue/vapor';
103103
104104
export function render(_ctx) {
105105
const t0 = _template("<div></div>")
106106
const n0 = t0()
107107
const { 0: [n1],} = _children(n0)
108108
_renderEffect(() => {
109-
_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)
109+
_setDOMProp(n1, "fooBar", undefined, _ctx.id)
110110
})
111111
return n0
112112
}"
@@ -127,14 +127,14 @@ export function render(_ctx) {
127127
`;
128128
129129
exports[`compiler v-bind > .prop modifier w/ no expression 1`] = `
130-
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
130+
"import { template as _template, children as _children, renderEffect as _renderEffect, setDOMProp as _setDOMProp } from 'vue/vapor';
131131
132132
export function render(_ctx) {
133133
const t0 = _template("<div></div>")
134134
const n0 = t0()
135135
const { 0: [n1],} = _children(n0)
136136
_renderEffect(() => {
137-
_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)
137+
_setDOMProp(n1, "fooBar", undefined, _ctx.fooBar)
138138
})
139139
return n0
140140
}"

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ export function render(_ctx) {
1313
`;
1414

1515
exports[`compiler: v-once > basic 1`] = `
16-
"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setDynamicProp as _setDynamicProp, prepend as _prepend } from 'vue/vapor';
16+
"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setClass as _setClass, prepend as _prepend } from 'vue/vapor';
1717
1818
export function render(_ctx) {
1919
const t0 = _template("<div> <span></span></div>")
2020
const n0 = t0()
2121
const { 0: [n3, { 1: [n2],}],} = _children(n0)
2222
const n1 = _createTextNode(_ctx.msg)
2323
_setText(n1, undefined, _ctx.msg)
24-
_setDynamicProp(n2, "class", undefined, _ctx.clz)
24+
_setClass(n2, "class", undefined, _ctx.clz)
2525
_prepend(n3, n1)
2626
return n0
2727
}"

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

+32-19
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ describe('compiler v-bind', () => {
189189
content: `id`,
190190
isStatic: false,
191191
},
192+
runtimeCamelize: false,
193+
modifier: undefined,
192194
})
193195

194196
expect(code).matchSnapshot()
@@ -207,6 +209,8 @@ describe('compiler v-bind', () => {
207209
content: `fooBar`,
208210
isStatic: false,
209211
},
212+
runtimeCamelize: false,
213+
modifier: undefined,
210214
})
211215

212216
expect(code).matchSnapshot()
@@ -220,7 +224,6 @@ describe('compiler v-bind', () => {
220224
const { ir, code } = compileWithVBind(`<div v-bind:[foo].camel="id"/>`)
221225

222226
expect(ir.effect[0].operations[0]).toMatchObject({
223-
runtimeCamelize: true,
224227
key: {
225228
content: `foo`,
226229
isStatic: false,
@@ -229,6 +232,8 @@ describe('compiler v-bind', () => {
229232
content: `id`,
230233
isStatic: false,
231234
},
235+
runtimeCamelize: true,
236+
modifier: undefined,
232237
})
233238

234239
expect(code).matchSnapshot()
@@ -245,39 +250,41 @@ describe('compiler v-bind', () => {
245250

246251
expect(ir.effect[0].operations[0]).toMatchObject({
247252
key: {
248-
content: `.fooBar`,
253+
content: `fooBar`,
249254
isStatic: true,
250255
},
251256
value: {
252257
content: `id`,
253258
isStatic: false,
254259
},
260+
runtimeCamelize: false,
261+
modifier: '.',
255262
})
256263

257264
expect(code).matchSnapshot()
258265
expect(code).contains('renderEffect')
259-
expect(code).contains('_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)')
266+
expect(code).contains('_setDOMProp(n1, "fooBar", undefined, _ctx.id)')
260267
})
261268

262269
test('.prop modifier w/ no expression', () => {
263270
const { ir, code } = compileWithVBind(`<div v-bind:fooBar.prop />`)
264271

265272
expect(ir.effect[0].operations[0]).toMatchObject({
266273
key: {
267-
content: `.fooBar`,
274+
content: `fooBar`,
268275
isStatic: true,
269276
},
270277
value: {
271278
content: `fooBar`,
272279
isStatic: false,
273280
},
281+
runtimeCamelize: false,
282+
modifier: '.',
274283
})
275284

276285
expect(code).matchSnapshot()
277286
expect(code).contains('renderEffect')
278-
expect(code).contains(
279-
'_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)',
280-
)
287+
expect(code).contains('_setDOMProp(n1, "fooBar", undefined, _ctx.fooBar)')
281288
})
282289

283290
test('.prop modifier w/ dynamic arg', () => {
@@ -292,6 +299,8 @@ describe('compiler v-bind', () => {
292299
content: `id`,
293300
isStatic: false,
294301
},
302+
runtimeCamelize: false,
303+
modifier: '.',
295304
})
296305

297306
expect(code).matchSnapshot()
@@ -308,78 +317,82 @@ describe('compiler v-bind', () => {
308317

309318
expect(ir.effect[0].operations[0]).toMatchObject({
310319
key: {
311-
content: `.fooBar`,
320+
content: `fooBar`,
312321
isStatic: true,
313322
},
314323
value: {
315324
content: `id`,
316325
isStatic: false,
317326
},
327+
runtimeCamelize: false,
328+
modifier: '.',
318329
})
319330

320331
expect(code).matchSnapshot()
321332
expect(code).contains('renderEffect')
322-
expect(code).contains('_setDynamicProp(n1, ".fooBar", undefined, _ctx.id)')
333+
expect(code).contains('_setDOMProp(n1, "fooBar", undefined, _ctx.id)')
323334
})
324335

325336
test('.prop modifier (shortband) w/ no expression', () => {
326337
const { ir, code } = compileWithVBind(`<div .fooBar />`)
327338

328339
expect(ir.effect[0].operations[0]).toMatchObject({
329340
key: {
330-
content: `.fooBar`,
341+
content: `fooBar`,
331342
isStatic: true,
332343
},
333344
value: {
334345
content: `fooBar`,
335346
isStatic: false,
336347
},
348+
runtimeCamelize: false,
349+
modifier: '.',
337350
})
338351

339352
expect(code).matchSnapshot()
340353
expect(code).contains('renderEffect')
341-
expect(code).contains(
342-
'_setDynamicProp(n1, ".fooBar", undefined, _ctx.fooBar)',
343-
)
354+
expect(code).contains('_setDOMProp(n1, "fooBar", undefined, _ctx.fooBar)')
344355
})
345356

346357
test('.attr modifier', () => {
347358
const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.attr="id"/>`)
348359

349360
expect(ir.effect[0].operations[0]).toMatchObject({
350361
key: {
351-
content: `^foo-bar`,
362+
content: `foo-bar`,
352363
isStatic: true,
353364
},
354365
value: {
355366
content: `id`,
356367
isStatic: false,
357368
},
369+
runtimeCamelize: false,
370+
modifier: '^',
358371
})
359372

360373
expect(code).matchSnapshot()
361374
expect(code).contains('renderEffect')
362-
expect(code).contains('_setDynamicProp(n1, "^foo-bar", undefined, _ctx.id)')
375+
expect(code).contains('_setAttr(n1, "foo-bar", undefined, _ctx.id)')
363376
})
364377

365378
test('.attr modifier w/ no expression', () => {
366379
const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.attr />`)
367380

368381
expect(ir.effect[0].operations[0]).toMatchObject({
369382
key: {
370-
content: `^foo-bar`,
383+
content: `foo-bar`,
371384
isStatic: true,
372385
},
373386
value: {
374387
content: `fooBar`,
375388
isStatic: false,
376389
},
390+
runtimeCamelize: false,
391+
modifier: '^',
377392
})
378393

379394
expect(code).matchSnapshot()
380395
expect(code).contains('renderEffect')
381-
expect(code).contains(
382-
'_setDynamicProp(n1, "^foo-bar", undefined, _ctx.fooBar)',
383-
)
396+
expect(code).contains('_setAttr(n1, "foo-bar", undefined, _ctx.fooBar)')
384397
})
385398
})

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

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,56 @@
11
import type { CodegenContext } from '../generate'
22
import type { SetPropIRNode } from '../ir'
33
import { genExpression } from './expression'
4+
import { isString } from '@vue/shared'
45

56
export function genSetProp(oper: SetPropIRNode, context: CodegenContext) {
67
const { pushFnCall, pushMulti, newline, vaporHelper, helper } = context
78

89
newline()
10+
11+
const element = `n${oper.element}`
12+
13+
// fast path for static props
14+
if (isString(oper.key) || oper.key.isStatic) {
15+
const keyName = isString(oper.key) ? oper.key : oper.key.content
16+
17+
let helperName: string | undefined
18+
if (keyName === 'class') {
19+
helperName = 'setClass'
20+
} else if (keyName === 'style') {
21+
helperName = 'setStyle'
22+
} else if (oper.modifier) {
23+
helperName = oper.modifier === '.' ? 'setDOMProp' : 'setAttr'
24+
}
25+
26+
if (helperName) {
27+
pushFnCall(
28+
vaporHelper(helperName),
29+
element,
30+
() => {
31+
const expr = () => genExpression(oper.key, context)
32+
if (oper.runtimeCamelize) {
33+
pushFnCall(helper('camelize'), expr)
34+
} else {
35+
expr()
36+
}
37+
},
38+
'undefined',
39+
() => genExpression(oper.value, context),
40+
)
41+
return
42+
}
43+
}
44+
945
pushFnCall(
1046
vaporHelper('setDynamicProp'),
11-
`n${oper.element}`,
47+
element,
1248
// 2. key name
1349
() => {
1450
if (oper.runtimeCamelize) {
1551
pushFnCall(helper('camelize'), () => genExpression(oper.key, context))
16-
} else if (oper.runtimePrefix) {
17-
pushMulti([`\`${oper.runtimePrefix}\${`, `}\``], () =>
52+
} else if (oper.modifier) {
53+
pushMulti([`\`${oper.modifier}\${`, `}\``], () =>
1854
genExpression(oper.key, context),
1955
)
2056
} else {

packages/compiler-vapor/src/ir.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ export interface SetPropIRNode extends BaseIRNode {
6363
element: number
6464
key: IRExpression
6565
value: IRExpression
66+
modifier?: '.' | '^'
6667
runtimeCamelize: boolean
67-
runtimePrefix?: string
6868
}
6969

7070
export interface SetTextIRNode extends BaseIRNode {

0 commit comments

Comments
 (0)