mirror of https://github.com/vuejs/core.git
wip(vapor): align compiler with new props runtime behavior
This commit is contained in:
parent
59b1aeda51
commit
23ba438be1
|
@ -100,9 +100,7 @@ exports[`compiler: element transform > component > should wrap as function if v-
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
{ onBar: () => $event => (_ctx.handleBar($event)) }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Foo, { onBar: () => $event => (_ctx.handleBar($event)) }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -112,12 +110,10 @@ exports[`compiler: element transform > component > static props 1`] = `
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
{
|
||||
id: () => ("foo"),
|
||||
class: () => ("bar")
|
||||
}
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Foo, {
|
||||
id: () => ("foo"),
|
||||
class: () => ("bar")
|
||||
}, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -127,9 +123,9 @@ exports[`compiler: element transform > component > v-bind="obj" 1`] = `
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
const n0 = _createComponent(_component_Foo, { $: [
|
||||
() => (_ctx.obj)
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -139,10 +135,12 @@ exports[`compiler: element transform > component > v-bind="obj" after static pro
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
{ id: () => ("foo") },
|
||||
() => (_ctx.obj)
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Foo, {
|
||||
id: () => ("foo"),
|
||||
$: [
|
||||
() => (_ctx.obj)
|
||||
]
|
||||
}, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -152,10 +150,10 @@ exports[`compiler: element transform > component > v-bind="obj" before static pr
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
const n0 = _createComponent(_component_Foo, { $: [
|
||||
() => (_ctx.obj),
|
||||
{ id: () => ("foo") }
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -165,11 +163,13 @@ exports[`compiler: element transform > component > v-bind="obj" between static p
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
{ id: () => ("foo") },
|
||||
() => (_ctx.obj),
|
||||
{ class: () => ("bar") }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Foo, {
|
||||
id: () => ("foo"),
|
||||
$: [
|
||||
() => (_ctx.obj),
|
||||
{ class: () => ("bar") }
|
||||
]
|
||||
}, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -179,9 +179,9 @@ exports[`compiler: element transform > component > v-on="obj" 1`] = `
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
const n0 = _createComponent(_component_Foo, { $: [
|
||||
() => (_toHandlers(_ctx.obj))
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -192,10 +192,10 @@ import { resolveComponent as _resolveComponent, createComponent as _createCompon
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
const n0 = _createComponent(_component_Foo, { $: [
|
||||
() => ({ [_toHandlerKey(_ctx.foo-_ctx.bar)]: () => _ctx.bar }),
|
||||
() => ({ [_toHandlerKey(_ctx.baz)]: () => _ctx.qux })
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -205,10 +205,10 @@ exports[`compiler: element transform > component with dynamic prop arguments 1`]
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Foo = _resolveComponent("Foo")
|
||||
const n0 = _createComponent(_component_Foo, [
|
||||
const n0 = _createComponent(_component_Foo, { $: [
|
||||
() => ({ [_ctx.foo-_ctx.bar]: _ctx.bar }),
|
||||
() => ({ [_ctx.baz]: _ctx.qux })
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -245,9 +245,7 @@ exports[`compiler: element transform > dynamic component > normal component with
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_custom_input = _resolveComponent("custom-input")
|
||||
const n0 = _createComponent(_component_custom_input, [
|
||||
{ is: () => ("foo") }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_custom_input, { is: () => ("foo") }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -27,9 +27,7 @@ exports[`compiler: transform <slot> outlets > default slot outlet with props & f
|
|||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("default", [
|
||||
{ foo: () => (_ctx.bar) }
|
||||
], () => {
|
||||
const n0 = _createSlot("default", { foo: () => (_ctx.bar) }, () => {
|
||||
const n2 = t0()
|
||||
return n2
|
||||
})
|
||||
|
@ -41,13 +39,11 @@ exports[`compiler: transform <slot> outlets > default slot outlet with props 1`]
|
|||
"import { createSlot as _createSlot } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("default", [
|
||||
{
|
||||
foo: () => ("bar"),
|
||||
baz: () => (_ctx.qux),
|
||||
fooBar: () => (_ctx.foo-_ctx.bar)
|
||||
}
|
||||
])
|
||||
const n0 = _createSlot("default", {
|
||||
foo: () => ("bar"),
|
||||
baz: () => (_ctx.qux),
|
||||
fooBar: () => (_ctx.foo-_ctx.bar)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -107,9 +103,7 @@ exports[`compiler: transform <slot> outlets > named slot outlet with props & fal
|
|||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("foo", [
|
||||
{ foo: () => (_ctx.bar) }
|
||||
], () => {
|
||||
const n0 = _createSlot("foo", { foo: () => (_ctx.bar) }, () => {
|
||||
const n2 = t0()
|
||||
return n2
|
||||
})
|
||||
|
@ -130,12 +124,10 @@ exports[`compiler: transform <slot> outlets > statically named slot outlet with
|
|||
"import { createSlot as _createSlot } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("foo", [
|
||||
{
|
||||
foo: () => ("bar"),
|
||||
baz: () => (_ctx.qux)
|
||||
}
|
||||
])
|
||||
const n0 = _createSlot("foo", {
|
||||
foo: () => ("bar"),
|
||||
baz: () => (_ctx.qux)
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -144,11 +136,13 @@ exports[`compiler: transform <slot> outlets > statically named slot outlet with
|
|||
"import { createSlot as _createSlot } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("foo", [
|
||||
{ foo: () => ("bar") },
|
||||
() => (_ctx.obj),
|
||||
{ baz: () => (_ctx.qux) }
|
||||
])
|
||||
const n0 = _createSlot("foo", {
|
||||
foo: () => ("bar"),
|
||||
$: [
|
||||
() => (_ctx.obj),
|
||||
{ baz: () => (_ctx.qux) }
|
||||
]
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -157,11 +151,13 @@ exports[`compiler: transform <slot> outlets > statically named slot outlet with
|
|||
"import { createSlot as _createSlot, toHandlers as _toHandlers } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = _createSlot("default", [
|
||||
{ onClick: () => _ctx.foo },
|
||||
() => (_toHandlers(_ctx.bar)),
|
||||
{ baz: () => (_ctx.qux) }
|
||||
])
|
||||
const n0 = _createSlot("default", {
|
||||
onClick: () => _ctx.foo,
|
||||
$: [
|
||||
() => (_toHandlers(_ctx.bar)),
|
||||
{ baz: () => (_ctx.qux) }
|
||||
]
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -464,9 +464,7 @@ exports[`compiler v-bind > number value 1`] = `
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{ depth: () => (0) }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Comp, { depth: () => (0) }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -5,11 +5,9 @@ exports[`compiler: vModel transform > component > v-model for component should g
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{ modelValue: () => (_ctx.foo),
|
||||
"onUpdate:modelValue": () => $event => (_ctx.foo = $event),
|
||||
modelModifiers: () => ({ trim: true, "bar-baz": true }) }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Comp, { modelValue: () => (_ctx.foo),
|
||||
"onUpdate:modelValue": () => $event => (_ctx.foo = $event),
|
||||
modelModifiers: () => ({ trim: true, "bar-baz": true }) }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -19,10 +17,8 @@ exports[`compiler: vModel transform > component > v-model for component should w
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{ modelValue: () => (_ctx.foo),
|
||||
"onUpdate:modelValue": () => $event => (_ctx.foo = $event) }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Comp, { modelValue: () => (_ctx.foo),
|
||||
"onUpdate:modelValue": () => $event => (_ctx.foo = $event) }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -32,16 +28,14 @@ exports[`compiler: vModel transform > component > v-model with arguments for com
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{
|
||||
foo: () => (_ctx.foo),
|
||||
"onUpdate:foo": () => $event => (_ctx.foo = $event),
|
||||
fooModifiers: () => ({ trim: true }),
|
||||
bar: () => (_ctx.bar),
|
||||
"onUpdate:bar": () => $event => (_ctx.bar = $event),
|
||||
barModifiers: () => ({ number: true })
|
||||
}
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Comp, {
|
||||
foo: () => (_ctx.foo),
|
||||
"onUpdate:foo": () => $event => (_ctx.foo = $event),
|
||||
fooModifiers: () => ({ trim: true }),
|
||||
bar: () => (_ctx.bar),
|
||||
"onUpdate:bar": () => $event => (_ctx.bar = $event),
|
||||
barModifiers: () => ({ number: true })
|
||||
}, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -51,10 +45,8 @@ exports[`compiler: vModel transform > component > v-model with arguments for com
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{ bar: () => (_ctx.foo),
|
||||
"onUpdate:bar": () => $event => (_ctx.foo = $event) }
|
||||
], null, true)
|
||||
const n0 = _createComponent(_component_Comp, { bar: () => (_ctx.foo),
|
||||
"onUpdate:bar": () => $event => (_ctx.foo = $event) }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -64,14 +56,14 @@ exports[`compiler: vModel transform > component > v-model with dynamic arguments
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
const n0 = _createComponent(_component_Comp, { $: [
|
||||
() => ({ [_ctx.foo]: _ctx.foo,
|
||||
["onUpdate:" + _ctx.foo]: () => $event => (_ctx.foo = $event),
|
||||
[_ctx.foo + "Modifiers"]: () => ({ trim: true }) }),
|
||||
() => ({ [_ctx.bar]: _ctx.bar,
|
||||
["onUpdate:" + _ctx.bar]: () => $event => (_ctx.bar = $event),
|
||||
[_ctx.bar + "Modifiers"]: () => ({ number: true }) })
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
@ -81,10 +73,10 @@ exports[`compiler: vModel transform > component > v-model with dynamic arguments
|
|||
|
||||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
const n0 = _createComponent(_component_Comp, { $: [
|
||||
() => ({ [_ctx.arg]: _ctx.foo,
|
||||
["onUpdate:" + _ctx.arg]: () => $event => (_ctx.foo = $event) })
|
||||
], null, true)
|
||||
] }, null, true)
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -43,9 +43,7 @@ const t0 = _template("<div></div>")
|
|||
export function render(_ctx) {
|
||||
const _component_Comp = _resolveComponent("Comp")
|
||||
const n1 = t0()
|
||||
const n0 = _createComponent(_component_Comp, [
|
||||
{ id: () => (_ctx.foo) }
|
||||
], null, null, true)
|
||||
const n0 = _createComponent(_component_Comp, { id: () => (_ctx.foo) }, null, null, true)
|
||||
_insert(n0, n1)
|
||||
return n1
|
||||
}"
|
||||
|
|
|
@ -199,12 +199,10 @@ describe('compiler: element transform', () => {
|
|||
)
|
||||
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(code).contains(`[
|
||||
{
|
||||
id: () => ("foo"),
|
||||
class: () => ("bar")
|
||||
}
|
||||
]`)
|
||||
expect(code).contains(`{
|
||||
id: () => ("foo"),
|
||||
class: () => ("bar")
|
||||
}`)
|
||||
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
|
@ -273,10 +271,12 @@ describe('compiler: element transform', () => {
|
|||
`<Foo id="foo" v-bind="obj" />`,
|
||||
)
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(code).contains(`[
|
||||
{ id: () => ("foo") },
|
||||
() => (_ctx.obj)
|
||||
]`)
|
||||
expect(code).contains(`{
|
||||
id: () => ("foo"),
|
||||
$: [
|
||||
() => (_ctx.obj)
|
||||
]
|
||||
}`)
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.CREATE_COMPONENT_NODE,
|
||||
|
@ -321,11 +321,13 @@ describe('compiler: element transform', () => {
|
|||
`<Foo id="foo" v-bind="obj" class="bar" />`,
|
||||
)
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(code).contains(`[
|
||||
{ id: () => ("foo") },
|
||||
() => (_ctx.obj),
|
||||
{ class: () => ("bar") }
|
||||
]`)
|
||||
expect(code).contains(`{
|
||||
id: () => ("foo"),
|
||||
$: [
|
||||
() => (_ctx.obj),
|
||||
{ class: () => ("bar") }
|
||||
]
|
||||
}`)
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
type: IRNodeTypes.CREATE_COMPONENT_NODE,
|
||||
|
|
|
@ -208,9 +208,9 @@ describe('compiler: vModel transform', () => {
|
|||
test('v-model for component should work', () => {
|
||||
const { code, ir } = compileWithVModel('<Comp v-model="foo" />')
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(code).contains(`modelValue: () => (_ctx.foo),`)
|
||||
expect(code).contains(
|
||||
`modelValue: () => (_ctx.foo),
|
||||
"onUpdate:modelValue": () => $event => (_ctx.foo = $event)`,
|
||||
`"onUpdate:modelValue": () => $event => (_ctx.foo = $event)`,
|
||||
)
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
|
@ -233,9 +233,9 @@ describe('compiler: vModel transform', () => {
|
|||
test('v-model with arguments for component should work', () => {
|
||||
const { code, ir } = compileWithVModel('<Comp v-model:bar="foo" />')
|
||||
expect(code).toMatchSnapshot()
|
||||
expect(code).contains(`bar: () => (_ctx.foo),`)
|
||||
expect(code).contains(
|
||||
`bar: () => (_ctx.foo),
|
||||
"onUpdate:bar": () => $event => (_ctx.foo = $event)`,
|
||||
`"onUpdate:bar": () => $event => (_ctx.foo = $event)`,
|
||||
)
|
||||
expect(ir.block.operation).toMatchObject([
|
||||
{
|
||||
|
|
|
@ -40,19 +40,19 @@ import { genModelHandler } from './modelValue'
|
|||
import { genBlock } from './block'
|
||||
|
||||
export function genCreateComponent(
|
||||
oper: CreateComponentIRNode,
|
||||
operation: CreateComponentIRNode,
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] {
|
||||
const { vaporHelper } = context
|
||||
|
||||
const tag = genTag()
|
||||
const { root, props, slots, once } = oper
|
||||
const { root, props, slots, once } = operation
|
||||
const rawProps = genRawProps(props, context)
|
||||
const rawSlots = genRawSlots(slots, context)
|
||||
|
||||
return [
|
||||
NEWLINE,
|
||||
`const n${oper.id} = `,
|
||||
`const n${operation.id} = `,
|
||||
...genCall(
|
||||
vaporHelper('createComponent'),
|
||||
tag,
|
||||
|
@ -61,20 +61,20 @@ export function genCreateComponent(
|
|||
root ? 'true' : false,
|
||||
once && 'true',
|
||||
),
|
||||
...genDirectivesForElement(oper.id, context),
|
||||
...genDirectivesForElement(operation.id, context),
|
||||
]
|
||||
|
||||
function genTag() {
|
||||
if (oper.dynamic) {
|
||||
if (operation.dynamic) {
|
||||
return genCall(
|
||||
vaporHelper('resolveDynamicComponent'),
|
||||
genExpression(oper.dynamic, context),
|
||||
genExpression(operation.dynamic, context),
|
||||
)
|
||||
} else if (oper.asset) {
|
||||
return toValidAssetId(oper.tag, 'component')
|
||||
} else if (operation.asset) {
|
||||
return toValidAssetId(operation.tag, 'component')
|
||||
} else {
|
||||
return genExpression(
|
||||
extend(createSimpleExpression(oper.tag, false), { ast: null }),
|
||||
extend(createSimpleExpression(operation.tag, false), { ast: null }),
|
||||
context,
|
||||
)
|
||||
}
|
||||
|
@ -85,41 +85,65 @@ export function genRawProps(
|
|||
props: IRProps[],
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] | undefined {
|
||||
const { vaporHelper } = context
|
||||
const frag = props
|
||||
.map(props => {
|
||||
if (isArray(props)) {
|
||||
if (!props.length) return
|
||||
return genStaticProps(props, context)
|
||||
} else {
|
||||
let expr: CodeFragment[]
|
||||
if (props.kind === IRDynamicPropsKind.ATTRIBUTE)
|
||||
expr = genMulti(DELIMITERS_OBJECT, genProp(props, context))
|
||||
else {
|
||||
expr = genExpression(props.value, context)
|
||||
if (props.handler) expr = genCall(vaporHelper('toHandlers'), expr)
|
||||
}
|
||||
return ['() => (', ...expr, ')']
|
||||
}
|
||||
})
|
||||
.filter(
|
||||
Boolean as any as (v: CodeFragment[] | undefined) => v is CodeFragment[],
|
||||
const staticProps = props[0]
|
||||
if (isArray(staticProps)) {
|
||||
if (!staticProps.length && props.length === 1) {
|
||||
return
|
||||
}
|
||||
return genStaticProps(
|
||||
staticProps,
|
||||
context,
|
||||
genDynamicProps(props.slice(1), context),
|
||||
)
|
||||
if (frag.length) {
|
||||
return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frag)
|
||||
} else if (props.length) {
|
||||
// all dynamic
|
||||
return genStaticProps([], context, genDynamicProps(props, context))
|
||||
}
|
||||
}
|
||||
|
||||
function genStaticProps(
|
||||
props: IRPropsStatic,
|
||||
context: CodegenContext,
|
||||
dynamicProps?: CodeFragment[],
|
||||
): CodeFragment[] {
|
||||
const args = props.map(prop => genProp(prop, context, true))
|
||||
if (dynamicProps) {
|
||||
args.push([`$: `, ...dynamicProps])
|
||||
}
|
||||
return genMulti(
|
||||
props.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT,
|
||||
...props.map(prop => genProp(prop, context, true)),
|
||||
args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT,
|
||||
...args,
|
||||
)
|
||||
}
|
||||
|
||||
function genDynamicProps(
|
||||
props: IRProps[],
|
||||
context: CodegenContext,
|
||||
): CodeFragment[] | undefined {
|
||||
const { vaporHelper } = context
|
||||
const frags: CodeFragment[][] = []
|
||||
for (const p of props) {
|
||||
let expr: CodeFragment[]
|
||||
if (isArray(p)) {
|
||||
if (p.length) {
|
||||
frags.push(genStaticProps(p, context))
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
if (p.kind === IRDynamicPropsKind.ATTRIBUTE)
|
||||
expr = genMulti(DELIMITERS_OBJECT, genProp(p, context))
|
||||
else {
|
||||
expr = genExpression(p.value, context)
|
||||
if (p.handler) expr = genCall(vaporHelper('toHandlers'), expr)
|
||||
}
|
||||
}
|
||||
frags.push(['() => (', ...expr, ')'])
|
||||
}
|
||||
if (frags.length) {
|
||||
return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags)
|
||||
}
|
||||
}
|
||||
|
||||
function genProp(prop: IRProp, context: CodegenContext, isStatic?: boolean) {
|
||||
const values = genPropValue(prop.values, context)
|
||||
return [
|
||||
|
|
|
@ -76,10 +76,11 @@ export function createComponent(
|
|||
// check if we are the single root of the parent
|
||||
// if yes, inject parent attrs as dynamic props source
|
||||
if (isSingleRoot && currentInstance && currentInstance.hasFallthrough) {
|
||||
const attrs = currentInstance.attrs
|
||||
if (rawProps) {
|
||||
;(rawProps.$ || (rawProps.$ = [])).push(currentInstance.attrs)
|
||||
;(rawProps.$ || (rawProps.$ = [])).push(() => attrs)
|
||||
} else {
|
||||
rawProps = { $: [currentInstance.attrs] }
|
||||
rawProps = { $: [() => attrs] } as RawProps
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,14 +8,13 @@ import {
|
|||
} from '@vue/runtime-dom'
|
||||
import { normalizeEmitsOptions } from './componentEmits'
|
||||
|
||||
export interface RawProps {
|
||||
[key: string]: PropSource
|
||||
export type RawProps = Record<string, () => unknown> & {
|
||||
$?: DynamicPropsSource[]
|
||||
}
|
||||
|
||||
type PropSource<T = any> = T | (() => T)
|
||||
|
||||
type DynamicPropsSource = PropSource<Record<string, any>>
|
||||
type DynamicPropsSource =
|
||||
| (() => Record<string, unknown>)
|
||||
| Record<string, () => unknown>
|
||||
|
||||
export function initStaticProps(
|
||||
comp: VaporComponent,
|
||||
|
@ -38,40 +37,24 @@ export function initStaticProps(
|
|||
const needCast = needCastKeys && needCastKeys.includes(normalizedKey)
|
||||
const source = rawProps[key]
|
||||
if (propsOptions && normalizedKey in propsOptions) {
|
||||
if (isFunction(source)) {
|
||||
Object.defineProperty(props, normalizedKey, {
|
||||
enumerable: true,
|
||||
get: needCast
|
||||
? () =>
|
||||
resolvePropValue(
|
||||
propsOptions,
|
||||
normalizedKey,
|
||||
source(),
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
: source,
|
||||
})
|
||||
} else {
|
||||
props[normalizedKey] = needCast
|
||||
? resolvePropValue(
|
||||
propsOptions,
|
||||
normalizedKey,
|
||||
source,
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
: source
|
||||
}
|
||||
Object.defineProperty(props, normalizedKey, {
|
||||
enumerable: true,
|
||||
get: needCast
|
||||
? () =>
|
||||
resolvePropValue(
|
||||
propsOptions,
|
||||
normalizedKey,
|
||||
source(),
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
: source,
|
||||
})
|
||||
} else if (!isEmitListener(emitsOptions, key)) {
|
||||
if (isFunction(source)) {
|
||||
Object.defineProperty(attrs, key, {
|
||||
enumerable: true,
|
||||
get: source,
|
||||
})
|
||||
} else {
|
||||
attrs[normalizedKey] = source
|
||||
}
|
||||
Object.defineProperty(attrs, key, {
|
||||
enumerable: true,
|
||||
get: source,
|
||||
})
|
||||
hasAttrs = true
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +81,9 @@ function resolveDefault(
|
|||
}
|
||||
|
||||
// TODO optimization: maybe convert functions into computeds
|
||||
export function resolveSource(source: PropSource): Record<string, any> {
|
||||
export function resolveSource(
|
||||
source: Record<string, any> | (() => Record<string, any>),
|
||||
): Record<string, any> {
|
||||
return isFunction(source) ? source() : source
|
||||
}
|
||||
|
||||
|
@ -138,15 +123,18 @@ export function getDynamicPropsHandlers(
|
|||
: passThrough
|
||||
|
||||
if (key in target) {
|
||||
return castProp(resolveSource(target[key as string]))
|
||||
return castProp(target[key as string]())
|
||||
}
|
||||
if (target.$) {
|
||||
let i = target.$.length
|
||||
let source
|
||||
const dynamicSources = target.$
|
||||
if (dynamicSources) {
|
||||
let i = dynamicSources.length
|
||||
let source, isDynamic
|
||||
while (i--) {
|
||||
source = resolveSource(target.$[i])
|
||||
source = dynamicSources[i]
|
||||
isDynamic = isFunction(source)
|
||||
source = isDynamic ? (source as Function)() : source
|
||||
if (hasOwn(source, key)) {
|
||||
return castProp(source[key])
|
||||
return castProp(isDynamic ? source[key] : source[key]())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,12 +162,14 @@ export function getDynamicPropsHandlers(
|
|||
: null
|
||||
|
||||
const hasAttr = (target: RawProps, key: string) => {
|
||||
if (key === '$' || isProp(key) || isEmitListener(emitsOptions, key))
|
||||
if (key === '$' || isProp(key) || isEmitListener(emitsOptions, key)) {
|
||||
return false
|
||||
if (target.$) {
|
||||
let i = target.$.length
|
||||
}
|
||||
const dynamicSources = target.$
|
||||
if (dynamicSources) {
|
||||
let i = dynamicSources.length
|
||||
while (i--) {
|
||||
if (hasOwn(resolveSource(target.$[i]), key)) {
|
||||
if (hasOwn(resolveSource(dynamicSources[i]), key)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -201,10 +191,11 @@ export function getDynamicPropsHandlers(
|
|||
},
|
||||
ownKeys(target) {
|
||||
const keys = Object.keys(target)
|
||||
if (target.$) {
|
||||
let i = target.$.length
|
||||
const dynamicSources = target.$
|
||||
if (dynamicSources) {
|
||||
let i = dynamicSources.length
|
||||
while (i--) {
|
||||
keys.push(...Object.keys(resolveSource(target.$[i])))
|
||||
keys.push(...Object.keys(resolveSource(dynamicSources[i])))
|
||||
}
|
||||
}
|
||||
return keys.filter(key => hasAttr(target, key))
|
||||
|
|
Loading…
Reference in New Issue