feat(compiler-vapor): support implicit prop in template
This commit is contained in:
parent
51d9bbe7f0
commit
114d501524
|
@ -4,7 +4,7 @@ exports[`compile > bindings 1`] = `
|
|||
"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
|
||||
|
@ -56,7 +56,7 @@ exports[`compile > directives > custom directive > basic 1`] = `
|
|||
"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
|
||||
|
@ -67,7 +67,7 @@ exports[`compile > directives > custom directive > binding value 1`] = `
|
|||
"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
|
||||
|
@ -78,7 +78,7 @@ exports[`compile > directives > custom directive > dynamic parameters 1`] = `
|
|||
"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
|
||||
|
@ -89,7 +89,7 @@ exports[`compile > directives > custom directive > modifiers 1`] = `
|
|||
"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
|
||||
|
@ -100,7 +100,7 @@ exports[`compile > directives > custom directive > modifiers w/o binding 1`] = `
|
|||
"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
|
||||
|
@ -111,7 +111,7 @@ exports[`compile > directives > custom directive > static parameters 1`] = `
|
|||
"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
|
||||
|
@ -122,7 +122,7 @@ exports[`compile > directives > custom directive > static parameters and modifie
|
|||
"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
|
||||
|
@ -143,7 +143,7 @@ exports[`compile > directives > v-pre > basic 1`] = `
|
|||
"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
|
||||
}"
|
||||
|
@ -154,7 +154,7 @@ exports[`compile > directives > v-pre > should not affect siblings after it 1`]
|
|||
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()
|
||||
|
@ -190,14 +190,14 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// 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
|
||||
}"
|
||||
`;
|
|
@ -3,7 +3,7 @@
|
|||
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
|
||||
|
@ -14,7 +14,7 @@ exports[`compiler: element transform > component > generate multi root component
|
|||
"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]
|
||||
|
@ -24,7 +24,7 @@ export function render(_ctx) {
|
|||
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
|
||||
}"
|
||||
|
@ -41,14 +41,14 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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
|
||||
})()"
|
||||
|
@ -57,14 +57,14 @@ exports[`compiler: element transform > component > resolve component from setup
|
|||
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
|
||||
})()"
|
||||
|
@ -73,14 +73,14 @@ exports[`compiler: element transform > component > resolve namespaced component
|
|||
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
|
||||
})()"
|
||||
|
@ -89,7 +89,7 @@ exports[`compiler: element transform > component > resolve namespaced component
|
|||
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
|
||||
}"
|
||||
|
|
|
@ -4,7 +4,7 @@ exports[`v-html > should convert v-html to innerHTML 1`] = `
|
|||
"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
|
||||
|
|
|
@ -177,7 +177,7 @@ exports[`compiler: vModel transform > should support member expression 1`] = `
|
|||
"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()
|
||||
|
@ -192,7 +192,7 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`compiler: vModel transform > should support member expression w/ inline 1`] = `
|
||||
"(() => {
|
||||
"((_ctx) => {
|
||||
const n0 = t0()
|
||||
_withDirectives(n0, [[_vModelText, () => setupRef.value.child]])
|
||||
const n1 = t0()
|
||||
|
|
|
@ -65,7 +65,7 @@ const t2 = _template("<div></div>")
|
|||
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()
|
||||
|
@ -448,7 +448,7 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
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()
|
||||
|
@ -493,7 +493,7 @@ exports[`v-on > simple expression 1`] = `
|
|||
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
|
||||
|
|
|
@ -15,7 +15,7 @@ exports[`compiler: v-once > basic 1`] = `
|
|||
"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, " "])
|
||||
|
|
|
@ -4,7 +4,7 @@ exports[`v-text > should convert v-text to textContent 1`] = `
|
|||
"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
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
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']`)
|
||||
})
|
||||
})
|
|
@ -104,13 +104,22 @@ export function generate(
|
|||
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)
|
||||
|
|
|
@ -132,8 +132,9 @@ function genIdentifier(
|
|||
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})`
|
||||
|
@ -167,7 +168,14 @@ function genIdentifier(
|
|||
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]]
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export {
|
|||
} from './transform'
|
||||
export {
|
||||
generate,
|
||||
type CodegenContext,
|
||||
CodegenContext,
|
||||
type CodegenOptions,
|
||||
type VaporCodegenResult,
|
||||
} from './generate'
|
||||
|
|
|
@ -81,7 +81,10 @@ export function setupComponent(
|
|||
component.render,
|
||||
instance,
|
||||
VaporErrorCodes.RENDER_FUNCTION,
|
||||
[instance.setupState],
|
||||
[
|
||||
instance.setupState, // _ctx
|
||||
__DEV__ ? shallowReadonly(props) : props, // $props
|
||||
],
|
||||
)
|
||||
resetTracking()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue