Skip to content

Commit 114d501

Browse files
committed
feat(compiler-vapor): support implicit prop in template
1 parent 51d9bbe commit 114d501

File tree

13 files changed

+119
-37
lines changed

13 files changed

+119
-37
lines changed

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`compile > bindings 1`] = `
44
"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
55
const t0 = _template("<div></div>")
66
7-
export function render(_ctx) {
7+
export function render(_ctx, $props) {
88
const n0 = t0()
99
_renderEffect(() => _setText(n0, "count is ", _ctx.count, "."))
1010
return n0
@@ -56,7 +56,7 @@ exports[`compile > directives > custom directive > basic 1`] = `
5656
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
5757
const t0 = _template("<div></div>")
5858
59-
export function render(_ctx) {
59+
export function render(_ctx, $props) {
6060
const n0 = t0()
6161
_withDirectives(n0, [[_ctx.vExample]])
6262
return n0
@@ -67,7 +67,7 @@ exports[`compile > directives > custom directive > binding value 1`] = `
6767
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
6868
const t0 = _template("<div></div>")
6969
70-
export function render(_ctx) {
70+
export function render(_ctx, $props) {
7171
const n0 = t0()
7272
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg]])
7373
return n0
@@ -78,7 +78,7 @@ exports[`compile > directives > custom directive > dynamic parameters 1`] = `
7878
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
7979
const t0 = _template("<div></div>")
8080
81-
export function render(_ctx) {
81+
export function render(_ctx, $props) {
8282
const n0 = t0()
8383
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, _ctx.foo]])
8484
return n0
@@ -89,7 +89,7 @@ exports[`compile > directives > custom directive > modifiers 1`] = `
8989
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
9090
const t0 = _template("<div></div>")
9191
92-
export function render(_ctx) {
92+
export function render(_ctx, $props) {
9393
const n0 = t0()
9494
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, void 0, { bar: true }]])
9595
return n0
@@ -100,7 +100,7 @@ exports[`compile > directives > custom directive > modifiers w/o binding 1`] = `
100100
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
101101
const t0 = _template("<div></div>")
102102
103-
export function render(_ctx) {
103+
export function render(_ctx, $props) {
104104
const n0 = t0()
105105
_withDirectives(n0, [[_ctx.vExample, void 0, void 0, { "foo-bar": true }]])
106106
return n0
@@ -111,7 +111,7 @@ exports[`compile > directives > custom directive > static parameters 1`] = `
111111
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
112112
const t0 = _template("<div></div>")
113113
114-
export function render(_ctx) {
114+
export function render(_ctx, $props) {
115115
const n0 = t0()
116116
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo"]])
117117
return n0
@@ -122,7 +122,7 @@ exports[`compile > directives > custom directive > static parameters and modifie
122122
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
123123
const t0 = _template("<div></div>")
124124
125-
export function render(_ctx) {
125+
export function render(_ctx, $props) {
126126
const n0 = t0()
127127
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo", { bar: true }]])
128128
return n0
@@ -143,7 +143,7 @@ exports[`compile > directives > v-pre > basic 1`] = `
143143
"import { template as _template } from 'vue/vapor';
144144
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
145145
146-
export function render(_ctx) {
146+
export function render(_ctx, $props) {
147147
const n0 = t0()
148148
return n0
149149
}"
@@ -154,7 +154,7 @@ exports[`compile > directives > v-pre > should not affect siblings after it 1`]
154154
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
155155
const t1 = _template("<div></div>")
156156
157-
export function render(_ctx) {
157+
export function render(_ctx, $props) {
158158
const _component_Comp = _resolveComponent("Comp")
159159
const n0 = t0()
160160
const n3 = t1()
@@ -190,14 +190,14 @@ export function render(_ctx) {
190190
`;
191191
192192
exports[`compile > expression parsing > interpolation 1`] = `
193-
"(() => {
193+
"((_ctx) => {
194194
const n0 = _createTextNode(() => [a + b.value])
195195
return n0
196196
})()"
197197
`;
198198
199199
exports[`compile > expression parsing > v-bind 1`] = `
200-
"(() => {
200+
"((_ctx) => {
201201
const n0 = t0()
202202
_renderEffect(() => _setDynamicProps(n0, { [key.value+1]: _unref(foo)[key.value+1]() }))
203203
return n0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`compiler: expression > basic 1`] = `
4+
"import { createTextNode as _createTextNode } from 'vue/vapor';
5+
6+
export function render(_ctx) {
7+
const n0 = _createTextNode(() => [_ctx.a])
8+
return n0
9+
}"
10+
`;
11+
12+
exports[`compiler: expression > props 1`] = `
13+
"import { createTextNode as _createTextNode } from 'vue/vapor';
14+
15+
export function render(_ctx, $props) {
16+
const n0 = _createTextNode(() => [$props.foo])
17+
return n0
18+
}"
19+
`;
20+
21+
exports[`compiler: expression > props aliased 1`] = `
22+
"import { createTextNode as _createTextNode } from 'vue/vapor';
23+
24+
export function render(_ctx, $props) {
25+
const n0 = _createTextNode(() => [$props['bar']])
26+
return n0
27+
}"
28+
`;

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`compiler: element transform > component > do not resolve component from non-script-setup bindings 1`] = `
44
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
55
6-
export function render(_ctx) {
6+
export function render(_ctx, $props) {
77
const _component_Example = _resolveComponent("Example")
88
const n0 = _createComponent(_component_Example, null, null, true)
99
return n0
@@ -14,7 +14,7 @@ exports[`compiler: element transform > component > generate multi root component
1414
"import { createComponent as _createComponent, template as _template } from 'vue/vapor';
1515
const t0 = _template("123")
1616
17-
export function render(_ctx) {
17+
export function render(_ctx, $props) {
1818
const n1 = t0()
1919
const n0 = _createComponent(_ctx.Comp)
2020
return [n0, n1]
@@ -24,7 +24,7 @@ export function render(_ctx) {
2424
exports[`compiler: element transform > component > generate single root component 1`] = `
2525
"import { createComponent as _createComponent } from 'vue/vapor';
2626
27-
export function render(_ctx) {
27+
export function render(_ctx, $props) {
2828
const n0 = _createComponent(_ctx.Comp, null, null, true)
2929
return n0
3030
}"
@@ -41,14 +41,14 @@ export function render(_ctx) {
4141
`;
4242

4343
exports[`compiler: element transform > component > resolve component from setup bindings (inline const) 1`] = `
44-
"(() => {
44+
"((_ctx) => {
4545
const n0 = _createComponent(Example, null, null, true)
4646
return n0
4747
})()"
4848
`;
4949

5050
exports[`compiler: element transform > component > resolve component from setup bindings (inline) 1`] = `
51-
"(() => {
51+
"((_ctx) => {
5252
const n0 = _createComponent(_unref(Example), null, null, true)
5353
return n0
5454
})()"
@@ -57,14 +57,14 @@ exports[`compiler: element transform > component > resolve component from setup
5757
exports[`compiler: element transform > component > resolve component from setup bindings 1`] = `
5858
"import { createComponent as _createComponent } from 'vue/vapor';
5959
60-
export function render(_ctx) {
60+
export function render(_ctx, $props) {
6161
const n0 = _createComponent(_ctx.Example, null, null, true)
6262
return n0
6363
}"
6464
`;
6565

6666
exports[`compiler: element transform > component > resolve namespaced component from props bindings (inline) 1`] = `
67-
"(() => {
67+
"((_ctx) => {
6868
const n0 = _createComponent(Foo.Example, null, null, true)
6969
return n0
7070
})()"
@@ -73,14 +73,14 @@ exports[`compiler: element transform > component > resolve namespaced component
7373
exports[`compiler: element transform > component > resolve namespaced component from props bindings (non-inline) 1`] = `
7474
"import { createComponent as _createComponent } from 'vue/vapor';
7575
76-
export function render(_ctx) {
76+
export function render(_ctx, $props) {
7777
const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
7878
return n0
7979
}"
8080
`;
8181

8282
exports[`compiler: element transform > component > resolve namespaced component from setup bindings (inline const) 1`] = `
83-
"(() => {
83+
"((_ctx) => {
8484
const n0 = _createComponent(Foo.Example, null, null, true)
8585
return n0
8686
})()"
@@ -89,7 +89,7 @@ exports[`compiler: element transform > component > resolve namespaced component
8989
exports[`compiler: element transform > component > resolve namespaced component from setup bindings 1`] = `
9090
"import { createComponent as _createComponent } from 'vue/vapor';
9191
92-
export function render(_ctx) {
92+
export function render(_ctx, $props) {
9393
const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
9494
return n0
9595
}"

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`v-html > should convert v-html to innerHTML 1`] = `
44
"import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
55
const t0 = _template("<div></div>")
66
7-
export function render(_ctx) {
7+
export function render(_ctx, $props) {
88
const n0 = t0()
99
_renderEffect(() => _setHtml(n0, _ctx.code))
1010
return n0

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ exports[`compiler: vModel transform > should support member expression 1`] = `
177177
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
178178
const t0 = _template("<input>")
179179
180-
export function render(_ctx) {
180+
export function render(_ctx, $props) {
181181
const n0 = t0()
182182
_withDirectives(n0, [[_vModelText, () => _ctx.setupRef.child]])
183183
const n1 = t0()
@@ -192,7 +192,7 @@ export function render(_ctx) {
192192
`;
193193
194194
exports[`compiler: vModel transform > should support member expression w/ inline 1`] = `
195-
"(() => {
195+
"((_ctx) => {
196196
const n0 = t0()
197197
_withDirectives(n0, [[_vModelText, () => setupRef.value.child]])
198198
const n1 = t0()

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const t2 = _template("<div></div>")
6565
const t3 = _template("<input>")
6666
_delegateEvents("click", "contextmenu", "mouseup", "keyup")
6767
68-
export function render(_ctx) {
68+
export function render(_ctx, $props) {
6969
const n0 = t0()
7070
const n1 = t1()
7171
const n2 = t0()
@@ -448,7 +448,7 @@ export function render(_ctx) {
448448
`;
449449
450450
exports[`v-on > should wrap in unref if identifier is setup-maybe-ref w/ inline: true 1`] = `
451-
"(() => {
451+
"((_ctx) => {
452452
const n0 = t0()
453453
const n1 = t0()
454454
const n2 = t0()
@@ -493,7 +493,7 @@ exports[`v-on > simple expression 1`] = `
493493
const t0 = _template("<div></div>")
494494
_delegateEvents("click")
495495
496-
export function render(_ctx) {
496+
export function render(_ctx, $props) {
497497
const n0 = t0()
498498
_delegate(n0, "click", () => _ctx.handleClick)
499499
return n0

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ exports[`compiler: v-once > basic 1`] = `
1515
"import { createTextNode as _createTextNode, setClass as _setClass, prepend as _prepend, template as _template } from 'vue/vapor';
1616
const t0 = _template("<div><span></span></div>")
1717
18-
export function render(_ctx) {
18+
export function render(_ctx, $props) {
1919
const n2 = t0()
2020
const n1 = n2.firstChild
2121
const n0 = _createTextNode([_ctx.msg, " "])

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`v-text > should convert v-text to textContent 1`] = `
44
"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
55
const t0 = _template("<div></div>")
66
7-
export function render(_ctx) {
7+
export function render(_ctx, $props) {
88
const n0 = t0()
99
_renderEffect(() => _setText(n0, _ctx.str))
1010
return n0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { BindingTypes } from '@vue/compiler-dom'
2+
import { transformChildren, transformText } from '../../src'
3+
import { makeCompile } from './_utils'
4+
5+
const compileWithExpression = makeCompile({
6+
nodeTransforms: [transformChildren, transformText],
7+
})
8+
9+
describe('compiler: expression', () => {
10+
test('basic', () => {
11+
const { code } = compileWithExpression(`{{ a }}`)
12+
expect(code).toMatchSnapshot()
13+
expect(code).contains(`ctx.a`)
14+
})
15+
16+
test('props', () => {
17+
const { code } = compileWithExpression(`{{ foo }}`, {
18+
bindingMetadata: { foo: BindingTypes.PROPS },
19+
})
20+
expect(code).toMatchSnapshot()
21+
expect(code).contains(`$props.foo`)
22+
})
23+
24+
test('props aliased', () => {
25+
const { code } = compileWithExpression(`{{ foo }}`, {
26+
bindingMetadata: {
27+
foo: BindingTypes.PROPS_ALIASED,
28+
__propsAliases: { foo: 'bar' } as any,
29+
},
30+
})
31+
expect(code).toMatchSnapshot()
32+
expect(code).contains(`$props['bar']`)
33+
})
34+
})

packages/compiler-vapor/src/generate.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,22 @@ export function generate(
104104
const [frag, push] = buildCodeFragment()
105105
const context = new CodegenContext(ir, options)
106106
const { helpers, vaporHelpers } = context
107-
const { inline } = options
107+
const { inline, bindingMetadata } = options
108108
const functionName = 'render'
109109

110+
const args = ['_ctx']
111+
if (bindingMetadata && !inline) {
112+
// binding optimization args
113+
args.push('$props')
114+
}
115+
const signature = (options.isTS ? args.map(arg => `${arg}: any`) : args).join(
116+
', ',
117+
)
118+
110119
if (inline) {
111-
push(`(() => {`)
120+
push(`((${signature}) => {`)
112121
} else {
113-
push(NEWLINE, `export function ${functionName}(_ctx) {`)
122+
push(NEWLINE, `export function ${functionName}(${signature}) {`)
114123
}
115124

116125
push(INDENT_START)

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ function genIdentifier(
132132
prefix = `${raw}: `
133133
}
134134

135+
const type = bindingMetadata[raw]
135136
if (inline) {
136-
switch (bindingMetadata[raw]) {
137+
switch (type) {
137138
case BindingTypes.SETUP_LET:
138139
name = raw = assignment
139140
? `_isRef(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})`
@@ -167,7 +168,14 @@ function genIdentifier(
167168
raw = withAssignment(raw)
168169
}
169170
} else {
170-
raw = withAssignment(canPrefix(raw) ? `_ctx.${raw}` : raw)
171+
if (canPrefix(raw)) {
172+
if (type === BindingTypes.PROPS_ALIASED) {
173+
raw = `$props['${bindingMetadata.__propsAliases![raw]}']`
174+
} else {
175+
raw = `${type === BindingTypes.PROPS ? '$props' : '_ctx'}.${raw}`
176+
}
177+
}
178+
raw = withAssignment(raw)
171179
}
172180
return [prefix, [raw, NewlineType.None, loc, name]]
173181

packages/compiler-vapor/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export {
99
} from './transform'
1010
export {
1111
generate,
12-
type CodegenContext,
12+
CodegenContext,
1313
type CodegenOptions,
1414
type VaporCodegenResult,
1515
} from './generate'

0 commit comments

Comments
 (0)