"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_renderEffect(() => _setText(n0, "count is ", _ctx.count, "."))
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, _ctx.foo]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, void 0, { bar: true }]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, void 0, void 0, { "foo-bar": true }]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo"]])
return n0
"import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo", { bar: true }]])
return n0
"import { template as _template } from 'vue/vapor';
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
return n0
}"
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
const t1 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const _component_Comp = _resolveComponent("Comp")
const n0 = t0()
const n3 = t1()
`;
exports[`compile > expression parsing > interpolation 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = _createTextNode(() => [a + b.value])
return n0
})()"
`;
exports[`compile > expression parsing > v-bind 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = t0()
_renderEffect(() => _setDynamicProps(n0, { [key.value+1]: _unref(foo)[key.value+1]() }))
return n0
--- /dev/null
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`compiler: expression > basic 1`] = `
+"import { createTextNode as _createTextNode } from 'vue/vapor';
+
+export function render(_ctx) {
+ const n0 = _createTextNode(() => [_ctx.a])
+ return n0
+}"
+`;
+
+exports[`compiler: expression > props 1`] = `
+"import { createTextNode as _createTextNode } from 'vue/vapor';
+
+export function render(_ctx, $props) {
+ const n0 = _createTextNode(() => [$props.foo])
+ return n0
+}"
+`;
+
+exports[`compiler: expression > props aliased 1`] = `
+"import { createTextNode as _createTextNode } from 'vue/vapor';
+
+export function render(_ctx, $props) {
+ const n0 = _createTextNode(() => [$props['bar']])
+ return n0
+}"
+`;
exports[`compiler: element transform > component > do not resolve component from non-script-setup bindings 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
-export function render(_ctx) {
+export function render(_ctx, $props) {
const _component_Example = _resolveComponent("Example")
const n0 = _createComponent(_component_Example, null, null, true)
return n0
"import { createComponent as _createComponent, template as _template } from 'vue/vapor';
const t0 = _template("123")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n1 = t0()
const n0 = _createComponent(_ctx.Comp)
return [n0, n1]
exports[`compiler: element transform > component > generate single root component 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = _createComponent(_ctx.Comp, null, null, true)
return n0
}"
`;
exports[`compiler: element transform > component > resolve component from setup bindings (inline const) 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = _createComponent(Example, null, null, true)
return n0
})()"
`;
exports[`compiler: element transform > component > resolve component from setup bindings (inline) 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = _createComponent(_unref(Example), null, null, true)
return n0
})()"
exports[`compiler: element transform > component > resolve component from setup bindings 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = _createComponent(_ctx.Example, null, null, true)
return n0
}"
`;
exports[`compiler: element transform > component > resolve namespaced component from props bindings (inline) 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = _createComponent(Foo.Example, null, null, true)
return n0
})()"
exports[`compiler: element transform > component > resolve namespaced component from props bindings (non-inline) 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
return n0
}"
`;
exports[`compiler: element transform > component > resolve namespaced component from setup bindings (inline const) 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = _createComponent(Foo.Example, null, null, true)
return n0
})()"
exports[`compiler: element transform > component > resolve namespaced component from setup bindings 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
return n0
}"
"import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_renderEffect(() => _setHtml(n0, _ctx.code))
return n0
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
const t0 = _template("<input>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_withDirectives(n0, [[_vModelText, () => _ctx.setupRef.child]])
const n1 = t0()
`;
exports[`compiler: vModel transform > should support member expression w/ inline 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = t0()
_withDirectives(n0, [[_vModelText, () => setupRef.value.child]])
const n1 = t0()
const t3 = _template("<input>")
_delegateEvents("click", "contextmenu", "mouseup", "keyup")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
const n1 = t1()
const n2 = t0()
`;
exports[`v-on > should wrap in unref if identifier is setup-maybe-ref w/ inline: true 1`] = `
-"(() => {
+"((_ctx) => {
const n0 = t0()
const n1 = t0()
const n2 = t0()
const t0 = _template("<div></div>")
_delegateEvents("click")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_delegate(n0, "click", () => _ctx.handleClick)
return n0
"import { createTextNode as _createTextNode, setClass as _setClass, prepend as _prepend, template as _template } from 'vue/vapor';
const t0 = _template("<div><span></span></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n2 = t0()
const n1 = n2.firstChild
const n0 = _createTextNode([_ctx.msg, " "])
"import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
-export function render(_ctx) {
+export function render(_ctx, $props) {
const n0 = t0()
_renderEffect(() => _setText(n0, _ctx.str))
return n0
--- /dev/null
+import { BindingTypes } from '@vue/compiler-dom'
+import { transformChildren, transformText } from '../../src'
+import { makeCompile } from './_utils'
+
+const compileWithExpression = makeCompile({
+ nodeTransforms: [transformChildren, transformText],
+})
+
+describe('compiler: expression', () => {
+ test('basic', () => {
+ const { code } = compileWithExpression(`{{ a }}`)
+ expect(code).toMatchSnapshot()
+ expect(code).contains(`ctx.a`)
+ })
+
+ test('props', () => {
+ const { code } = compileWithExpression(`{{ foo }}`, {
+ bindingMetadata: { foo: BindingTypes.PROPS },
+ })
+ expect(code).toMatchSnapshot()
+ expect(code).contains(`$props.foo`)
+ })
+
+ test('props aliased', () => {
+ const { code } = compileWithExpression(`{{ foo }}`, {
+ bindingMetadata: {
+ foo: BindingTypes.PROPS_ALIASED,
+ __propsAliases: { foo: 'bar' } as any,
+ },
+ })
+ expect(code).toMatchSnapshot()
+ expect(code).contains(`$props['bar']`)
+ })
+})
const [frag, push] = buildCodeFragment()
const context = new CodegenContext(ir, options)
const { helpers, vaporHelpers } = context
- const { inline } = options
+ const { inline, bindingMetadata } = options
const functionName = 'render'
+ const args = ['_ctx']
+ if (bindingMetadata && !inline) {
+ // binding optimization args
+ args.push('$props')
+ }
+ const signature = (options.isTS ? args.map(arg => `${arg}: any`) : args).join(
+ ', ',
+ )
+
if (inline) {
- push(`(() => {`)
+ push(`((${signature}) => {`)
} else {
- push(NEWLINE, `export function ${functionName}(_ctx) {`)
+ push(NEWLINE, `export function ${functionName}(${signature}) {`)
}
push(INDENT_START)
prefix = `${raw}: `
}
+ const type = bindingMetadata[raw]
if (inline) {
- switch (bindingMetadata[raw]) {
+ switch (type) {
case BindingTypes.SETUP_LET:
name = raw = assignment
? `_isRef(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})`
raw = withAssignment(raw)
}
} else {
- raw = withAssignment(canPrefix(raw) ? `_ctx.${raw}` : raw)
+ if (canPrefix(raw)) {
+ if (type === BindingTypes.PROPS_ALIASED) {
+ raw = `$props['${bindingMetadata.__propsAliases![raw]}']`
+ } else {
+ raw = `${type === BindingTypes.PROPS ? '$props' : '_ctx'}.${raw}`
+ }
+ }
+ raw = withAssignment(raw)
}
return [prefix, [raw, NewlineType.None, loc, name]]
} from './transform'
export {
generate,
- type CodegenContext,
+ CodegenContext,
type CodegenOptions,
type VaporCodegenResult,
} from './generate'
component.render,
instance,
VaporErrorCodes.RENDER_FUNCTION,
- [instance.setupState],
+ [
+ instance.setupState, // _ctx
+ __DEV__ ? shallowReadonly(props) : props, // $props
+ ],
)
resetTracking()
}