return function render() {
with (this) {
- const { createVNode: _createVNode, toString: _toString, openBlock: _openBlock, applyDirectives: _applyDirectives, createBlock: _createBlock, Empty: _Empty, Fragment: _Fragment, renderList: _renderList } = _Vue
+ const { createVNode: _createVNode, toString: _toString, openBlock: _openBlock, createBlock: _createBlock, Empty: _Empty, Fragment: _Fragment, renderList: _renderList } = _Vue
return _createVNode(\\"div\\", {
id: \\"foo\\",
}, [
_toString(world.burn()),
(_openBlock(), ok
- ? _createBlock(
- \\"div\\",
- { key: 0 },
- \\"yes\\"
- )
- : _createBlock(
- _Fragment,
- { key: 1 },
- \\"no\\"
- )),
+ ? _createBlock(\\"div\\", { key: 0 }, \\"yes\\")
+ : _createBlock(_Fragment, { key: 1 }, \\"no\\")),
_renderList(list, (value, index) => {
return _createVNode(\\"div\\", null, [
_createVNode(\\"span\\", null, _toString(value + index))
`;
exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = `
-"const { createVNode, toString, openBlock, applyDirectives, createBlock, Empty, Fragment, renderList } = Vue
+"const { createVNode, toString, openBlock, createBlock, Empty, Fragment, renderList } = Vue
return function render() {
const _ctx = this
}, [
toString(_ctx.world.burn()),
(openBlock(), (_ctx.ok)
- ? createBlock(
- \\"div\\",
- { key: 0 },
- \\"yes\\"
- )
- : createBlock(
- Fragment,
- { key: 1 },
- \\"no\\"
- )),
+ ? createBlock(\\"div\\", { key: 0 }, \\"yes\\")
+ : createBlock(Fragment, { key: 1 }, \\"no\\")),
renderList(_ctx.list, (value, index) => {
return createVNode(\\"div\\", null, [
createVNode(\\"span\\", null, toString(value + index))
`;
exports[`compiler: integration tests module mode 1`] = `
-"import { createVNode, toString, openBlock, applyDirectives, createBlock, Empty, Fragment, renderList } from \\"vue\\"
+"import { createVNode, toString, openBlock, createBlock, Empty, Fragment, renderList } from \\"vue\\"
export default function render() {
const _ctx = this
}, [
_toString(_ctx.world.burn()),
(openBlock(), (_ctx.ok)
- ? createBlock(
- \\"div\\",
- { key: 0 },
- \\"yes\\"
- )
- : createBlock(
- Fragment,
- { key: 1 },
- \\"no\\"
- )),
+ ? createBlock(\\"div\\", { key: 0 }, \\"yes\\")
+ : createBlock(Fragment, { key: 1 }, \\"no\\")),
_renderList(_ctx.list, (value, index) => {
return createVNode(\\"div\\", null, [
createVNode(\\"span\\", null, _toString(value + index))
--- /dev/null
+import { NodeTypes } from '../src'
+
+const leadingBracketRE = /^\[/
+const bracketsRE = /^\[|\]$/g
+
+// Create a matcher for an object
+// where non-static expressions should be wrapped in []
+// e.g.
+// - createObjectMatcher({ 'foo': '[bar]' }) matches { foo: bar }
+// - createObjectMatcher({ '[foo]': 'bar' }) matches { [foo]: "bar" }
+export function createObjectMatcher(obj: any) {
+ return {
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: Object.keys(obj).map(key => ({
+ type: NodeTypes.JS_PROPERTY,
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: key.replace(bracketsRE, ''),
+ isStatic: !leadingBracketRE.test(key)
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: obj[key].replace(bracketsRE, ''),
+ isStatic: !leadingBracketRE.test(obj[key])
+ }
+ }))
+ }
+}
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`compiler: transform v-if codegen basic v-if 1`] = `
+"const _Vue = Vue
+
+return function render() {
+ with (this) {
+ const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty } = _Vue
+
+ return (_openBlock(), ok
+ ? _createBlock(\\"div\\", { key: 0 })
+ : _createBlock(_Empty))
+ }
+}"
+`;
+
+exports[`compiler: transform v-if codegen template v-if 1`] = `
+"const _Vue = Vue
+
+return function render() {
+ with (this) {
+ const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Fragment: _Fragment, Empty: _Empty } = _Vue
+
+ return (_openBlock(), ok
+ ? _createBlock(_Fragment, { key: 0 }, [
+ _createVNode(\\"div\\"),
+ \\"hello\\",
+ _createVNode(\\"p\\")
+ ])
+ : _createBlock(_Empty))
+ }
+}"
+`;
+
+exports[`compiler: transform v-if codegen v-if + v-else 1`] = `
+"const _Vue = Vue
+
+return function render() {
+ with (this) {
+ const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty } = _Vue
+
+ return (_openBlock(), ok
+ ? _createBlock(\\"div\\", { key: 0 })
+ : _createBlock(\\"p\\", { key: 1 }))
+ }
+}"
+`;
+
+exports[`compiler: transform v-if codegen v-if + v-else-if + v-else 1`] = `
+"const _Vue = Vue
+
+return function render() {
+ with (this) {
+ const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty, Fragment: _Fragment } = _Vue
+
+ return (_openBlock(), ok
+ ? _createBlock(\\"div\\", { key: 0 })
+ : orNot
+ ? _createBlock(\\"p\\", { key: 1 })
+ : _createBlock(_Fragment, { key: 2 }, \\"fine\\"))
+ }
+}"
+`;
+
+exports[`compiler: transform v-if codegen v-if + v-else-if 1`] = `
+"const _Vue = Vue
+
+return function render() {
+ with (this) {
+ const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty } = _Vue
+
+ return (_openBlock(), ok
+ ? _createBlock(\\"div\\", { key: 0 })
+ : orNot
+ ? _createBlock(\\"p\\", { key: 1 })
+ : _createBlock(_Empty))
+ }
+}"
+`;
import { transformStyle } from '../../src/transforms/transformStyle'
import { transformBind } from '../../src/transforms/vBind'
import { PatchFlags } from '@vue/shared'
+import { createObjectMatcher } from '../testUtils'
function parseWithElementTransform(
template: string,
}
}
-function createStaticObjectMatcher(obj: any) {
- return {
- type: NodeTypes.JS_OBJECT_EXPRESSION,
- properties: Object.keys(obj).map(key => ({
- type: NodeTypes.JS_PROPERTY,
- key: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: key,
- isStatic: true
- },
- value: {
- type: NodeTypes.SIMPLE_EXPRESSION,
- content: obj[key],
- isStatic: true
- }
- }))
- }
-}
-
describe('compiler: element transform', () => {
test('import + resovle component', () => {
const { root } = parseWithElementTransform(`<Foo/>`)
expect(node.callee).toBe(`_${CREATE_VNODE}`)
expect(node.arguments).toMatchObject([
`"div"`,
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo',
class: 'bar'
})
expect(node.callee).toBe(`_${CREATE_VNODE}`)
expect(node.arguments).toMatchObject([
`"div"`,
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
}),
[
type: NodeTypes.JS_CALL_EXPRESSION,
callee: `_${MERGE_PROPS}`,
arguments: [
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
}),
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `obj`
},
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
})
]
type: NodeTypes.JS_CALL_EXPRESSION,
callee: `_${MERGE_PROPS}`,
arguments: [
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
}),
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `obj`
},
- createStaticObjectMatcher({
+ createObjectMatcher({
class: 'bar'
})
]
type: NodeTypes.JS_CALL_EXPRESSION,
callee: `_${MERGE_PROPS}`,
arguments: [
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
}),
{
}
]
},
- createStaticObjectMatcher({
+ createObjectMatcher({
class: 'bar'
})
]
type: NodeTypes.JS_CALL_EXPRESSION,
callee: `_${MERGE_PROPS}`,
arguments: [
- createStaticObjectMatcher({
+ createObjectMatcher({
id: 'foo'
}),
{
ElementNode,
TextNode,
CommentNode,
- SimpleExpressionNode
+ SimpleExpressionNode,
+ SequenceExpression,
+ ConditionalExpression,
+ CallExpression
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
-import { CompilerOptions } from '../../src'
+import { CompilerOptions, generate } from '../../src'
+import {
+ OPEN_BLOCK,
+ CREATE_BLOCK,
+ EMPTY,
+ FRAGMENT,
+ MERGE_PROPS,
+ APPLY_DIRECTIVES
+} from '../../src/runtimeConstants'
+import { createObjectMatcher } from '../testUtils'
function parseWithIfTransform(
template: string,
options: CompilerOptions = {},
returnIndex: number = 0
-): IfNode {
- const node = parse(template, options)
- transform(node, {
+) {
+ const ast = parse(template, options)
+ transform(ast, {
nodeTransforms: [transformIf, transformElement],
...options
})
if (!options.onError) {
- expect(node.children.length).toBe(1)
- expect(node.children[0].type).toBe(NodeTypes.IF)
+ expect(ast.children.length).toBe(1)
+ expect(ast.children[0].type).toBe(NodeTypes.IF)
+ }
+ return {
+ root: ast,
+ node: ast.children[returnIndex] as IfNode
}
- return node.children[returnIndex] as IfNode
}
describe('compiler: transform v-if', () => {
test('basic v-if', () => {
- const node = parseWithIfTransform(`<div v-if="ok"/>`)
+ const { node } = parseWithIfTransform(`<div v-if="ok"/>`)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(1)
expect((node.branches[0].condition as SimpleExpressionNode).content).toBe(
})
test('template v-if', () => {
- const node = parseWithIfTransform(
+ const { node } = parseWithIfTransform(
`<template v-if="ok"><div/>hello<p/></template>`
)
expect(node.type).toBe(NodeTypes.IF)
})
test('v-if + v-else', () => {
- const node = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`)
+ const { node } = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(2)
})
test('v-if + v-else-if', () => {
- const node = parseWithIfTransform(`<div v-if="ok"/><p v-else-if="orNot"/>`)
+ const { node } = parseWithIfTransform(
+ `<div v-if="ok"/><p v-else-if="orNot"/>`
+ )
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(2)
})
test('v-if + v-else-if + v-else', () => {
- const node = parseWithIfTransform(
+ const { node } = parseWithIfTransform(
`<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
)
expect(node.type).toBe(NodeTypes.IF)
})
test('comment between branches', () => {
- const node = parseWithIfTransform(`
+ const { node } = parseWithIfTransform(`
<div v-if="ok"/>
<!--foo-->
<p v-else-if="orNot"/>
})
test('should prefix v-if condition', () => {
- const node = parseWithIfTransform(`<div v-if="ok"/>`, {
+ const { node } = parseWithIfTransform(`<div v-if="ok"/>`, {
prefixIdentifiers: true
- }) as IfNode
+ })
expect(node.branches[0].condition).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_ctx.ok`
})
})
- describe('codegen', () => {
- // TODO
- })
-
describe('errors', () => {
test('error on v-else missing adjacent v-if', () => {
const onError = jest.fn()
- const node1 = parseWithIfTransform(`<div v-else/>`, { onError })
+ const { node: node1 } = parseWithIfTransform(`<div v-else/>`, { onError })
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
}
])
- const node2 = parseWithIfTransform(`<div/><div v-else/>`, { onError }, 1)
+ const { node: node2 } = parseWithIfTransform(
+ `<div/><div v-else/>`,
+ { onError },
+ 1
+ )
expect(onError.mock.calls[1]).toMatchObject([
{
code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
}
])
- const node3 = parseWithIfTransform(
+ const { node: node3 } = parseWithIfTransform(
`<div/>foo<div v-else/>`,
{ onError },
2
test('error on v-else-if missing adjacent v-if', () => {
const onError = jest.fn()
- const node1 = parseWithIfTransform(`<div v-else-if="foo"/>`, { onError })
+ const { node: node1 } = parseWithIfTransform(`<div v-else-if="foo"/>`, {
+ onError
+ })
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
}
])
- const node2 = parseWithIfTransform(
+ const { node: node2 } = parseWithIfTransform(
`<div/><div v-else-if="foo"/>`,
{ onError },
1
}
])
- const node3 = parseWithIfTransform(
+ const { node: node3 } = parseWithIfTransform(
`<div/>foo<div v-else-if="foo"/>`,
{ onError },
2
])
})
})
+
+ describe('codegen', () => {
+ function assertSharedCodegen(node: SequenceExpression, depth: number = 0) {
+ expect(node).toMatchObject({
+ type: NodeTypes.JS_SEQUENCE_EXPRESSION,
+ expressions: [
+ {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${OPEN_BLOCK}`,
+ arguments: []
+ },
+ {
+ type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
+ test: {
+ content: `ok`
+ },
+ consequent: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${CREATE_BLOCK}`
+ },
+ alternate:
+ depth < 1
+ ? {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${CREATE_BLOCK}`
+ }
+ : {
+ type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
+ test: {
+ content: `orNot`
+ },
+ consequent: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${CREATE_BLOCK}`
+ },
+ alternate: {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${CREATE_BLOCK}`
+ }
+ }
+ }
+ ]
+ })
+ }
+
+ test('basic v-if', () => {
+ const {
+ root,
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok"/>`)
+ assertSharedCodegen(codegenNode)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
+ const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
+ .alternate as CallExpression
+ expect(branch2.arguments).toMatchObject([`_${EMPTY}`])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('template v-if', () => {
+ const {
+ root,
+ node: { codegenNode }
+ } = parseWithIfTransform(`<template v-if="ok"><div/>hello<p/></template>`)
+ assertSharedCodegen(codegenNode)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments).toMatchObject([
+ `_${FRAGMENT}`,
+ `{ key: 0 }`,
+ [
+ { type: NodeTypes.ELEMENT, tag: 'div' },
+ { type: NodeTypes.TEXT, content: `hello` },
+ { type: NodeTypes.ELEMENT, tag: 'p' }
+ ]
+ ])
+ const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
+ .alternate as CallExpression
+ expect(branch2.arguments).toMatchObject([`_${EMPTY}`])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('v-if + v-else', () => {
+ const {
+ root,
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`)
+ assertSharedCodegen(codegenNode)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
+ const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
+ .alternate as CallExpression
+ expect(branch2.arguments).toMatchObject([`"p"`, `{ key: 1 }`])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('v-if + v-else-if', () => {
+ const {
+ root,
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok"/><p v-else-if="orNot" />`)
+ assertSharedCodegen(codegenNode, 1)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
+ const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
+ .alternate as ConditionalExpression
+ expect((branch2.consequent as CallExpression).arguments).toMatchObject([
+ `"p"`,
+ `{ key: 1 }`
+ ])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('v-if + v-else-if + v-else', () => {
+ const {
+ root,
+ node: { codegenNode }
+ } = parseWithIfTransform(
+ `<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
+ )
+ assertSharedCodegen(codegenNode, 1)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
+ const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
+ .alternate as ConditionalExpression
+ expect((branch2.consequent as CallExpression).arguments).toMatchObject([
+ `"p"`,
+ `{ key: 1 }`
+ ])
+ expect((branch2.alternate as CallExpression).arguments).toMatchObject([
+ `_${FRAGMENT}`,
+ `{ key: 2 }`,
+ [
+ {
+ type: NodeTypes.TEXT,
+ content: `fine`
+ }
+ ]
+ ])
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('key injection (only v-bind)', () => {
+ const {
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok" v-bind="obj"/>`)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${MERGE_PROPS}`,
+ arguments: [`{ key: 0 }`, { content: `obj` }]
+ })
+ })
+
+ test('key injection (before v-bind)', () => {
+ const {
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok" id="foo" v-bind="obj"/>`)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${MERGE_PROPS}`,
+ arguments: [
+ createObjectMatcher({
+ key: '[0]',
+ id: 'foo'
+ }),
+ { content: `obj` }
+ ]
+ })
+ })
+
+ test('key injection (after v-bind)', () => {
+ const {
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok" v-bind="obj" id="foo"/>`)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: `_${MERGE_PROPS}`,
+ arguments: [
+ `{ key: 0 }`,
+ { content: `obj` },
+ createObjectMatcher({
+ id: 'foo'
+ })
+ ]
+ })
+ })
+
+ test('key injection (w/ custom directive)', () => {
+ const {
+ node: { codegenNode }
+ } = parseWithIfTransform(`<div v-if="ok" v-foo />`)
+ const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
+ .consequent as CallExpression
+ expect(branch1.callee).toBe(`_${APPLY_DIRECTIVES}`)
+ const realBranch = branch1.arguments[0] as CallExpression
+ expect(realBranch.arguments[1]).toBe(`{ key: 0 }`)
+ })
+
+ test('with comments', () => {})
+ })
})
context: CodegenContext
) {
const multilines =
- nodes.length > 1 ||
+ nodes.length > 3 ||
((!__BROWSER__ || __DEV__) &&
nodes.some(
n =>
function genCallExpression(
node: CallExpression,
context: CodegenContext,
- multilines = node.arguments.length > 2
+ multilines = false
) {
context.push(node.callee + `(`, node, true)
multilines && context.indent()
JSChildNode,
ObjectExpression,
createObjectProperty,
- Property
+ Property,
+ ExpressionNode
} from '../ast'
import { createCompilerError, ErrorCodes } from '../errors'
import { processExpression } from './transformExpression'
CREATE_BLOCK,
EMPTY,
FRAGMENT,
- APPLY_DIRECTIVES
+ APPLY_DIRECTIVES,
+ MERGE_PROPS
} from '../runtimeConstants'
import { isString } from '@vue/shared'
}
if (dir.name === 'if') {
+ const branch = createIfBranch(node, dir)
const codegenNode = createSequenceExpression([
createCallExpression(context.helper(OPEN_BLOCK))
])
-
context.replaceNode({
type: NodeTypes.IF,
loc: node.loc,
- branches: [createIfBranch(node, dir)],
+ branches: [branch],
codegenNode
})
// transformed.
return () => {
codegenNode.expressions.push(
- createCodegenNodeForBranch(node, dir, 0, context)
+ createCodegenNodeForBranch(node, branch, 0, context)
)
}
} else {
} else {
parentCondition.alternate = createCodegenNodeForBranch(
node,
- dir,
+ branch,
sibling.branches.length - 1,
context
)
function createCodegenNodeForBranch(
node: ElementNode,
- dir: DirectiveNode,
+ branch: IfBranchNode,
index: number,
context: TransformContext
): ConditionalExpression | CallExpression {
- if (dir.exp) {
+ if (branch.condition) {
return createConditionalExpression(
- dir.exp,
- createChildrenCodegenNode(node, index, context),
+ branch.condition,
+ createChildrenCodegenNode(node, branch, index, context),
createCallExpression(context.helper(CREATE_BLOCK), [
context.helper(EMPTY)
])
)
} else {
- return createChildrenCodegenNode(node, index, context)
+ return createChildrenCodegenNode(node, branch, index, context)
}
}
function createChildrenCodegenNode(
node: ElementNode,
+ branch: IfBranchNode,
index: number,
{ helper }: TransformContext
): CallExpression {
return createCallExpression(helper(CREATE_BLOCK), [
helper(FRAGMENT),
keyExp,
- node.children
+ branch.children
])
} else {
let childCodegen = node.codegenNode!
- if (childCodegen.callee === helper(APPLY_DIRECTIVES)) {
+ if (childCodegen.callee.includes(APPLY_DIRECTIVES)) {
childCodegen = childCodegen.arguments[0] as CallExpression
}
// change child to a block
childCodegen.arguments[1] = keyExp
} else {
// inject branch key if not already have a key
- const props = existingProps as CallExpression | ObjectExpression
+ const props = existingProps as
+ | CallExpression
+ | ObjectExpression
+ | ExpressionNode
if (props.type === NodeTypes.JS_CALL_EXPRESSION) {
// merged props... add ours
// only inject key to object literal if it's the first argument so that
} else {
props.arguments.unshift(keyExp)
}
- } else {
+ } else if (props.type === NodeTypes.JS_OBJECT_EXPRESSION) {
props.properties.unshift(createKeyProperty(index))
+ } else {
+ // single v-bind with expression
+ childCodegen.arguments[1] = createCallExpression(helper(MERGE_PROPS), [
+ keyExp,
+ props
+ ])
}
}
- return childCodegen
+ return node.codegenNode!
}
}