perf: improve VNode creation performance with compiler hints (#3334)

This commit is contained in:
HcySunYang
2021-06-23 07:15:20 +08:00
committed by Evan You
parent 31abdc8ada
commit ceff89905b
42 changed files with 1130 additions and 685 deletions

View File

@@ -48,12 +48,12 @@ exports[`compiler: codegen Element (callExpression + objectExpression + Template
"
return function render(_ctx, _cache) {
with (_ctx) {
return _createVNode(\\"div\\", {
return _createElementVNode(\\"div\\", {
id: \\"foo\\",
[prop]: bar,
[foo + bar]: bar
}, [
_createVNode(\\"p\\", { \\"some-key\\": \\"foo\\" })
_createElementVNode(\\"p\\", { \\"some-key\\": \\"foo\\" })
], 16)
}
}"
@@ -98,7 +98,7 @@ exports[`compiler: codegen forNode 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(), 1))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1))
}
}"
`;
@@ -107,7 +107,7 @@ exports[`compiler: codegen forNode with constant expression 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
return (_openBlock(), _createBlock(_Fragment, null, _renderList(), 64 /* STABLE_FRAGMENT */))
return (_openBlock(), _createElementBlock(_Fragment, null, _renderList(), 64 /* STABLE_FRAGMENT */))
}
}"
`;

View File

@@ -5,21 +5,21 @@ exports[`compiler: integration tests function mode 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createVNode: _createVNode } = _Vue
const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createElementVNode: _createElementVNode, normalizeClass: _normalizeClass } = _Vue
return (_openBlock(), _createBlock(\\"div\\", {
return (_openBlock(), _createElementBlock(\\"div\\", {
id: \\"foo\\",
class: bar.baz
class: _normalizeClass(bar.baz)
}, [
_createTextVNode(_toDisplayString(world.burn()) + \\" \\", 1 /* TEXT */),
ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createBlock(_Fragment, { key: 1 }, [
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createElementBlock(_Fragment, { key: 1 }, [
_createTextVNode(\\"no\\")
], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (value, index) => {
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
]))
}), 256 /* UNKEYED_FRAGMENT */))
], 2 /* CLASS */))
@@ -28,22 +28,22 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createVNode: _createVNode } = Vue
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createElementVNode: _createElementVNode, normalizeClass: _normalizeClass } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", {
return (_openBlock(), _createElementBlock(\\"div\\", {
id: \\"foo\\",
class: _ctx.bar.baz
class: _normalizeClass(_ctx.bar.baz)
}, [
_createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */),
(_ctx.ok)
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createBlock(_Fragment, { key: 1 }, [
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createElementBlock(_Fragment, { key: 1 }, [
_createTextVNode(\\"no\\")
], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
]))
}), 256 /* UNKEYED_FRAGMENT */))
], 2 /* CLASS */))
@@ -51,22 +51,22 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: integration tests module mode 1`] = `
"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, Fragment as _Fragment, renderList as _renderList, createVNode as _createVNode } from \\"vue\\"
"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, Fragment as _Fragment, renderList as _renderList, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", {
return (_openBlock(), _createElementBlock(\\"div\\", {
id: \\"foo\\",
class: _ctx.bar.baz
class: _normalizeClass(_ctx.bar.baz)
}, [
_createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */),
(_ctx.ok)
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createBlock(_Fragment, { key: 1 }, [
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: (_openBlock(), _createElementBlock(_Fragment, { key: 1 }, [
_createTextVNode(\\"no\\")
], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
]))
}), 256 /* UNKEYED_FRAGMENT */))
], 2 /* CLASS */))

View File

@@ -1,16 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
"import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
_pushScopeId(\\"test\\")
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"div\\", null, \\"hello\\", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode(\\"div\\", null, \\"world\\", -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"div\\", null, \\"hello\\", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"div\\", null, \\"world\\", -1 /* HOISTED */)
_popScopeId()
export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1,
_createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */),
_hoisted_2
@@ -19,7 +19,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
`;
exports[`scopeId compiler support should wrap default slot 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
"import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
@@ -27,7 +27,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
return (_openBlock(), _createBlock(_component_Child, null, {
default: _withId(() => [
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
]),
_: 1 /* STABLE */
}))
@@ -35,7 +35,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
`;
exports[`scopeId compiler support should wrap dynamic slots 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
"import { createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
@@ -46,7 +46,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
? {
name: \\"foo\\",
fn: _withId(() => [
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
])
}
: undefined,
@@ -54,7 +54,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
return {
name: i,
fn: _withId(() => [
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
])
}
})
@@ -63,7 +63,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
`;
exports[`scopeId compiler support should wrap named slots 1`] = `
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
@@ -74,7 +74,7 @@ export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
_createTextVNode(_toDisplayString(msg), 1 /* TEXT */)
]),
bar: _withId(() => [
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
]),
_: 1 /* STABLE */
}))

View File

@@ -31,7 +31,8 @@ import {
RESOLVE_COMPONENT,
CREATE_COMMENT,
FRAGMENT,
RENDER_LIST
RENDER_LIST,
CREATE_ELEMENT_VNODE
} from '../src/runtimeHelpers'
import { createElementWithCodegen, genFlagText } from './testUtils'
import { PatchFlags } from '@vue/shared'
@@ -395,12 +396,12 @@ describe('compiler: codegen', () => {
})
)
expect(code).toMatch(`
return _${helperNameMap[CREATE_VNODE]}("div", {
return _${helperNameMap[CREATE_ELEMENT_VNODE]}("div", {
id: "foo",
[prop]: bar,
[foo + bar]: bar
}, [
_${helperNameMap[CREATE_VNODE]}("p", { "some-key": "foo" })
_${helperNameMap[CREATE_ELEMENT_VNODE]}("p", { "some-key": "foo" })
], ${PatchFlags.FULL_PROPS})`)
expect(code).toMatchSnapshot()
})
@@ -658,11 +659,11 @@ describe('compiler: codegen', () => {
test('tag only', () => {
expect(genCode(createVNodeCall(null, `"div"`))).toMatchInlineSnapshot(`
"return _createVNode(\\"div\\")
"return _createElementVNode(\\"div\\")
"
`)
expect(genCode(createVNodeCall(null, FRAGMENT))).toMatchInlineSnapshot(`
"return _createVNode(_Fragment)
"return _createElementVNode(_Fragment)
"
`)
})
@@ -670,7 +671,7 @@ describe('compiler: codegen', () => {
test('with props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", { foo: \\"bar\\" })
"return _createElementVNode(\\"div\\", { foo: \\"bar\\" })
"
`)
})
@@ -678,7 +679,7 @@ describe('compiler: codegen', () => {
test('with children, no props', () => {
expect(genCode(createVNodeCall(null, `"div"`, undefined, mockChildren)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", null, children)
"return _createElementVNode(\\"div\\", null, children)
"
`)
})
@@ -686,7 +687,7 @@ describe('compiler: codegen', () => {
test('with children + props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps, mockChildren)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", { foo: \\"bar\\" }, children)
"return _createElementVNode(\\"div\\", { foo: \\"bar\\" }, children)
"
`)
})
@@ -694,7 +695,7 @@ describe('compiler: codegen', () => {
test('with patchFlag and no children/props', () => {
expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", null, null, 1)
"return _createElementVNode(\\"div\\", null, null, 1)
"
`)
})
@@ -714,7 +715,7 @@ describe('compiler: codegen', () => {
)
)
).toMatchInlineSnapshot(`
"return (_openBlock(), _createBlock(\\"div\\", { foo: \\"bar\\" }, children))
"return (_openBlock(), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children))
"
`)
})
@@ -735,7 +736,7 @@ describe('compiler: codegen', () => {
)
)
).toMatchInlineSnapshot(`
"return (_openBlock(true), _createBlock(\\"div\\", { foo: \\"bar\\" }, children))
"return (_openBlock(true), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children))
"
`)
})
@@ -754,7 +755,7 @@ describe('compiler: codegen', () => {
)
)
).toMatchInlineSnapshot(`
"return _withDirectives(_createVNode(\\"div\\", { foo: \\"bar\\" }, children), [
"return _withDirectives(_createElementVNode(\\"div\\", { foo: \\"bar\\" }, children), [
[foo, bar]
])
"
@@ -776,7 +777,7 @@ describe('compiler: codegen', () => {
)
)
).toMatchInlineSnapshot(`
"return _withDirectives((_openBlock(), _createBlock(\\"div\\", { foo: \\"bar\\" }, children)), [
"return _withDirectives((_openBlock(), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children)), [
[foo, bar]
])
"

View File

@@ -73,10 +73,10 @@ describe('scopeId compiler support', () => {
expect(code).toMatch(
[
`_pushScopeId("test")`,
`const _hoisted_1 = /*#__PURE__*/_createVNode("div", null, "hello", ${genFlagText(
`const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "hello", ${genFlagText(
PatchFlags.HOISTED
)})`,
`const _hoisted_2 = /*#__PURE__*/_createVNode("div", null, "world", ${genFlagText(
`const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, "world", ${genFlagText(
PatchFlags.HOISTED
)})`,
`_popScopeId()`

View File

@@ -6,7 +6,13 @@ import {
ElementTypes,
VNodeCall
} from '../src'
import { isString, PatchFlags, PatchFlagNames, isArray } from '@vue/shared'
import {
isString,
PatchFlags,
PatchFlagNames,
isArray,
ShapeFlags
} from '@vue/shared'
const leadingBracketRE = /^\[/
const bracketsRE = /^\[|\]$/g
@@ -63,19 +69,25 @@ export function createElementWithCodegen(
directives: undefined,
isBlock: false,
disableTracking: false,
isComponent: false,
shapeFlag: ShapeFlags.ELEMENT + ``,
loc: locStub
}
}
}
export function genFlagText(flag: PatchFlags | PatchFlags[]) {
type Flags = PatchFlags | ShapeFlags
export function genFlagText(
flag: Flags | Flags[],
names: { [k: number]: string } = PatchFlagNames
) {
if (isArray(flag)) {
let f = 0
flag.forEach(ff => {
f |= ff
})
return `${f} /* ${flag.map(f => PatchFlagNames[f]).join(', ')} */`
return `${f} /* ${flag.map(f => names[f]).join(', ')} */`
} else {
return `${flag} /* ${PatchFlagNames[flag]} */`
return `${flag} /* ${names[flag]} */`
}
}

View File

@@ -2,15 +2,15 @@
exports[`compiler: hoistStatic transform hoist element with static key 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"div\\", { key: \\"foo\\" }, null, -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"div\\", { key: \\"foo\\" }, null, -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -19,18 +19,18 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist nested static tree 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"p\\", null, [
/*#__PURE__*/_createVNode(\\"span\\"),
/*#__PURE__*/_createVNode(\\"span\\")
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"p\\", null, [
/*#__PURE__*/_createElementVNode(\\"span\\"),
/*#__PURE__*/_createElementVNode(\\"span\\")
], -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -39,17 +39,17 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist nested static tree with comments 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"div\\", null, [
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"div\\", null, [
/*#__PURE__*/_createCommentVNode(\\"comment\\")
], -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createCommentVNode: _createCommentVNode, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -58,16 +58,16 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist siblings with common non-hoistable parent 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"span\\", null, null, -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode(\\"div\\", null, null, -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"span\\", null, null, -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"div\\", null, null, -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1,
_hoisted_2
]))
@@ -77,15 +77,15 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist simple element 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\", -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\", -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -94,18 +94,18 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist static props for elements with directives 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) {
with (_ctx) {
const { resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveDirective: _resolveDirective, createElementVNode: _createElementVNode, withDirectives: _withDirectives, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
return (_openBlock(), _createBlock(\\"div\\", null, [
_withDirectives(_createVNode(\\"div\\", _hoisted_1, null, 512 /* NEED_PATCH */), [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_withDirectives(_createElementVNode(\\"div\\", _hoisted_1, null, 512 /* NEED_PATCH */), [
[_directive_foo]
])
]))
@@ -115,16 +115,16 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist static props for elements with dynamic text children 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", _hoisted_1, _toDisplayString(hello), 1 /* TEXT */)
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"div\\", _hoisted_1, _toDisplayString(hello), 1 /* TEXT */)
]))
}
}"
@@ -132,18 +132,18 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform hoist static props for elements with unhoistable children 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createVNode: _createVNode, createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) {
with (_ctx) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createVNode: _createVNode, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", _hoisted_1, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"div\\", _hoisted_1, [
_createVNode(_component_Comp)
])
]))
@@ -153,16 +153,18 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform prefixIdentifiers hoist class with static object value 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = { class: { foo: true } }
const _hoisted_1 = {
class: /*#__PURE__*/_normalizeClass({ foo: true })
}
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */)
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"span\\", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */)
]))
}
}"
@@ -170,15 +172,15 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static tree with static interpolation 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"span\\", null, \\"foo \\" + /*#__PURE__*/_toDisplayString(1) + \\" \\" + /*#__PURE__*/_toDisplayString(true), -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"span\\", null, \\"foo \\" + /*#__PURE__*/_toDisplayString(1) + \\" \\" + /*#__PURE__*/_toDisplayString(true), -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -187,15 +189,15 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static tree with static prop value 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"span\\", { foo: 0 }, /*#__PURE__*/_toDisplayString(1), -1 /* HOISTED */)
const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"span\\", { foo: 0 }, /*#__PURE__*/_toDisplayString(1), -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_hoisted_1
]))
}
@@ -203,12 +205,12 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", null, [
_createVNode(\\"div\\", {
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"div\\", null, [
_createElementVNode(\\"div\\", {
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.foo && _ctx.foo(...args)))
})
])
@@ -221,12 +223,12 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
return (_openBlock(), _createBlock(\\"p\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(o + 'foo'), 1 /* TEXT */)
return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
return (_openBlock(), _createElementBlock(\\"p\\", null, [
_createElementVNode(\\"span\\", null, _toDisplayString(o + 'foo'), 1 /* TEXT */)
]))
}), 256 /* UNKEYED_FRAGMENT */))
]))
@@ -258,12 +260,12 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
return (_openBlock(), _createBlock(\\"p\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(o), 1 /* TEXT */)
return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
return (_openBlock(), _createElementBlock(\\"p\\", null, [
_createElementVNode(\\"span\\", null, _toDisplayString(o), 1 /* TEXT */)
]))
}), 256 /* UNKEYED_FRAGMENT */))
]))
@@ -276,11 +278,11 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist keye
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\", { key: item }))
return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(\\"span\\", { key: item }))
}), 128 /* KEYED_FRAGMENT */))
]))
}
@@ -292,11 +294,11 @@ exports[`compiler: hoistStatic transform should NOT hoist components 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createVNode(_component_Comp)
]))
}
@@ -308,10 +310,10 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic k
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(), _createBlock(\\"div\\", { key: foo }))
return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(), _createElementBlock(\\"div\\", { key: foo }))
]))
}
}"
@@ -322,10 +324,10 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic p
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
]))
}
}"
@@ -336,10 +338,10 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic r
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { ref: foo }, null, 512 /* NEED_PATCH */)
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_createElementVNode(\\"div\\", { ref: foo }, null, 512 /* NEED_PATCH */)
]))
}
}"
@@ -350,27 +352,27 @@ exports[`compiler: hoistStatic transform should NOT hoist root node 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\"))
return (_openBlock(), _createElementBlock(\\"div\\"))
}
}"
`;
exports[`compiler: hoistStatic transform should hoist v-for children if static 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode } = _Vue
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = { id: \\"foo\\" }
const _hoisted_2 = /*#__PURE__*/_createVNode(\\"span\\", null, null, -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"span\\", null, null, -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createBlock(\\"div\\", _hoisted_1, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createElementBlock(\\"div\\", _hoisted_1, [
_hoisted_2
]))
}), 256 /* UNKEYED_FRAGMENT */))
@@ -381,21 +383,21 @@ return function render(_ctx, _cache) {
exports[`compiler: hoistStatic transform should hoist v-if props/children if static 1`] = `
"const _Vue = Vue
const { createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
const { createElementVNode: _createElementVNode, createCommentVNode: _createCommentVNode } = _Vue
const _hoisted_1 = {
key: 0,
id: \\"foo\\"
}
const _hoisted_2 = /*#__PURE__*/_createVNode(\\"span\\", null, null, -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode(\\"span\\", null, null, -1 /* HOISTED */)
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
ok
? (_openBlock(), _createBlock(\\"div\\", _hoisted_1, [
? (_openBlock(), _createElementBlock(\\"div\\", _hoisted_1, [
_hoisted_2
]))
: _createCommentVNode(\\"v-if\\", true)

View File

@@ -2,14 +2,14 @@
exports[`compiler: expression transform bindingMetadata inline mode 1`] = `
"(_ctx, _cache) => {
return (_openBlock(), _createBlock(\\"div\\", null, _toDisplayString(__props.props) + \\" \\" + _toDisplayString(_unref(setup)) + \\" \\" + _toDisplayString(setupConst) + \\" \\" + _toDisplayString(_ctx.data) + \\" \\" + _toDisplayString(_ctx.options), 1 /* TEXT */))
return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString(__props.props) + \\" \\" + _toDisplayString(_unref(setup)) + \\" \\" + _toDisplayString(setupConst) + \\" \\" + _toDisplayString(_ctx.data) + \\" \\" + _toDisplayString(_ctx.options), 1 /* TEXT */))
}"
`;
exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = `
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options), 1 /* TEXT */))
return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options), 1 /* TEXT */))
}"
`;

View File

@@ -5,10 +5,10 @@ exports[`compiler: transform text <template v-for> 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createTextVNode: _createTextVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createTextVNode: _createTextVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createBlock(_Fragment, null, [
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createTextVNode(\\"foo\\")
], 64 /* STABLE_FRAGMENT */))
}), 256 /* UNKEYED_FRAGMENT */))
@@ -33,12 +33,12 @@ exports[`compiler: transform text consecutive text between elements 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createElementVNode(\\"div\\"),
_createTextVNode(_toDisplayString(foo) + \\" bar \\" + _toDisplayString(baz), 1 /* TEXT */),
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
], 64 /* STABLE_FRAGMENT */))
}
}"
@@ -49,14 +49,14 @@ exports[`compiler: transform text consecutive text mixed with elements 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createElementVNode(\\"div\\"),
_createTextVNode(_toDisplayString(foo) + \\" bar \\" + _toDisplayString(baz), 1 /* TEXT */),
_createVNode(\\"div\\"),
_createElementVNode(\\"div\\"),
_createTextVNode(\\"hello\\"),
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
], 64 /* STABLE_FRAGMENT */))
}
}"
@@ -67,11 +67,11 @@ exports[`compiler: transform text element with custom directives and only one te
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveDirective: _resolveDirective, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveDirective: _resolveDirective, withDirectives: _withDirectives, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
return _withDirectives((_openBlock(), _createBlock(\\"p\\", null, [
return _withDirectives((_openBlock(), _createElementBlock(\\"p\\", null, [
_createTextVNode(_toDisplayString(foo), 1 /* TEXT */)
], 512 /* NEED_PATCH */)), [
[_directive_foo]
@@ -97,12 +97,12 @@ exports[`compiler: transform text text between elements (static) 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createElementVNode(\\"div\\"),
_createTextVNode(\\"hello\\"),
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
], 64 /* STABLE_FRAGMENT */))
}
}"

View File

@@ -5,10 +5,10 @@ exports[`compiler: v-for codegen basic v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\"))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
@@ -19,12 +19,12 @@ exports[`compiler: v-for codegen keyed template v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(_Fragment, { key: item }, [
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(_Fragment, { key: item }, [
\\"hello\\",
_createVNode(\\"span\\")
_createElementVNode(\\"span\\")
], 64 /* STABLE_FRAGMENT */))
}), 128 /* KEYED_FRAGMENT */))
}
@@ -36,10 +36,10 @@ exports[`compiler: v-for codegen keyed v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\", { key: item }))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(\\"span\\", { key: item }))
}), 128 /* KEYED_FRAGMENT */))
}
}"
@@ -50,10 +50,10 @@ exports[`compiler: v-for codegen skipped key 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, __, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item, __, index) => {
return (_openBlock(), _createElementBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
@@ -64,10 +64,10 @@ exports[`compiler: v-for codegen skipped value & key 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, __, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (_, __, index) => {
return (_openBlock(), _createElementBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
@@ -78,10 +78,10 @@ exports[`compiler: v-for codegen skipped value 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, key, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (_, key, index) => {
return (_openBlock(), _createElementBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
@@ -92,12 +92,12 @@ exports[`compiler: v-for codegen template v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(_Fragment, null, [
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(_Fragment, null, [
\\"hello\\",
_createVNode(\\"span\\")
_createElementVNode(\\"span\\")
], 64 /* STABLE_FRAGMENT */))
}), 256 /* UNKEYED_FRAGMENT */))
}
@@ -109,10 +109,10 @@ exports[`compiler: v-for codegen template v-for key injection with single child
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\", {
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createElementBlock(\\"span\\", {
key: item.id,
id: item.id
}, null, 8 /* PROPS */, [\\"id\\"]))
@@ -126,9 +126,9 @@ exports[`compiler: v-for codegen template v-for w/ <slot/> 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, renderSlot: _renderSlot } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\")
}), 256 /* UNKEYED_FRAGMENT */))
}
@@ -140,9 +140,9 @@ exports[`compiler: v-for codegen v-for on <slot/> 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, renderSlot: _renderSlot } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\")
}), 256 /* UNKEYED_FRAGMENT */))
}
@@ -154,12 +154,12 @@ exports[`compiler: v-for codegen v-for on element with custom directive 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, resolveDirective: _resolveDirective, withDirectives: _withDirectives } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, resolveDirective: _resolveDirective, withDirectives: _withDirectives } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return _withDirectives((_openBlock(), _createBlock(\\"div\\", null, null, 512 /* NEED_PATCH */)), [
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(list, (i) => {
return _withDirectives((_openBlock(), _createElementBlock(\\"div\\", null, null, 512 /* NEED_PATCH */)), [
[_directive_foo]
])
}), 256 /* UNKEYED_FRAGMENT */))
@@ -172,10 +172,10 @@ exports[`compiler: v-for codegen v-for with constant expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, toDisplayString: _toDisplayString, createElementVNode: _createElementVNode } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, _renderList(10, (item) => {
return _createVNode(\\"p\\", null, _toDisplayString(item), 1 /* TEXT */)
return (_openBlock(), _createElementBlock(_Fragment, null, _renderList(10, (item) => {
return _createElementVNode(\\"p\\", null, _toDisplayString(item), 1 /* TEXT */)
}), 64 /* STABLE_FRAGMENT */))
}
}"
@@ -186,11 +186,11 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createBlock(\\"div\\"))
? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createElementBlock(\\"div\\"))
}), 256 /* UNKEYED_FRAGMENT */))
: _createCommentVNode(\\"v-if\\", true)
}
@@ -202,11 +202,11 @@ exports[`compiler: v-for codegen v-if + v-for on <template> 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createBlock(_Fragment, null, [], 64 /* STABLE_FRAGMENT */))
? (_openBlock(true), _createElementBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createElementBlock(_Fragment, null, [], 64 /* STABLE_FRAGMENT */))
}), 256 /* UNKEYED_FRAGMENT */))
: _createCommentVNode(\\"v-if\\", true)
}
@@ -218,10 +218,10 @@ exports[`compiler: v-for codegen value + key + index 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, key, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(items, (item, key, index) => {
return (_openBlock(), _createElementBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */))
}
}"

View File

@@ -5,10 +5,10 @@ exports[`compiler: v-if codegen basic v-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: _createCommentVNode(\\"v-if\\", true)
}
}"
@@ -19,17 +19,17 @@ exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] =
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
return (_openBlock(), _createElementBlock(_Fragment, null, [
ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: (_openBlock(), _createBlock(\\"p\\", { key: 1 })),
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: (_openBlock(), _createElementBlock(\\"p\\", { key: 1 })),
another
? (_openBlock(), _createBlock(\\"div\\", { key: 2 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 2 }))
: orNot
? (_openBlock(), _createBlock(\\"p\\", { key: 3 }))
: (_openBlock(), _createBlock(\\"p\\", { key: 4 }))
? (_openBlock(), _createElementBlock(\\"p\\", { key: 3 }))
: (_openBlock(), _createElementBlock(\\"p\\", { key: 4 }))
], 64 /* STABLE_FRAGMENT */))
}
}"
@@ -40,14 +40,14 @@ exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
return (_openBlock(), _createElementBlock(_Fragment, null, [
ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: _createCommentVNode(\\"v-if\\", true),
orNot
? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
? (_openBlock(), _createElementBlock(\\"p\\", { key: 1 }))
: _createCommentVNode(\\"v-if\\", true)
], 64 /* STABLE_FRAGMENT */))
}
@@ -59,13 +59,13 @@ exports[`compiler: v-if codegen template v-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { createElementVNode: _createElementVNode, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [
_createVNode(\\"div\\"),
? (_openBlock(), _createElementBlock(_Fragment, { key: 0 }, [
_createElementVNode(\\"div\\"),
\\"hello\\",
_createVNode(\\"p\\")
_createElementVNode(\\"p\\")
], 64 /* STABLE_FRAGMENT */))
: _createCommentVNode(\\"v-if\\", true)
}
@@ -91,11 +91,11 @@ exports[`compiler: v-if codegen v-if + v-else 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: (_openBlock(), _createElementBlock(\\"p\\", { key: 1 }))
}
}"
`;
@@ -105,13 +105,13 @@ exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: orNot
? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
: (_openBlock(), _createBlock(_Fragment, { key: 2 }, [\\"fine\\"], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
? (_openBlock(), _createElementBlock(\\"p\\", { key: 1 }))
: (_openBlock(), _createElementBlock(_Fragment, { key: 2 }, [\\"fine\\"], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
}
}"
`;
@@ -121,12 +121,12 @@ exports[`compiler: v-if codegen v-if + v-else-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }))
: orNot
? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
? (_openBlock(), _createElementBlock(\\"p\\", { key: 1 }))
: _createCommentVNode(\\"v-if\\", true)
}
}"

View File

@@ -1,10 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
modelValue: _ctx.model[_ctx.index],
\\"onUpdate:modelValue\\": $event => (_ctx.model[_ctx.index] = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
@@ -16,9 +16,9 @@ exports[`compiler: transform v-model compound expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
modelValue: model[index],
\\"onUpdate:modelValue\\": $event => (model[index] = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
@@ -31,9 +31,9 @@ exports[`compiler: transform v-model simple expression (with multilines) 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
modelValue:
model
.
@@ -50,10 +50,10 @@ foo
`;
exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = `
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
modelValue: _ctx.model,
\\"onUpdate:modelValue\\": $event => (_ctx.model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
@@ -65,9 +65,9 @@ exports[`compiler: transform v-model simple expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]))
@@ -80,9 +80,9 @@ exports[`compiler: transform v-model with argument 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", {
value: model,
\\"onUpdate:value\\": $event => (model = $event)
}, null, 40 /* PROPS, HYDRATE_EVENTS */, [\\"value\\", \\"onUpdate:value\\"]))
@@ -91,13 +91,13 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { normalizeProps as _normalizeProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", _normalizeProps({
[_ctx.value]: _ctx.model,
[\\"onUpdate:\\" + _ctx.value]: $event => (_ctx.model = $event)
}, null, 16 /* FULL_PROPS */))
}), null, 16 /* FULL_PROPS */))
}"
`;
@@ -106,12 +106,12 @@ exports[`compiler: transform v-model with dynamic argument 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { normalizeProps: _normalizeProps, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
return (_openBlock(), _createElementBlock(\\"input\\", _normalizeProps({
[value]: model,
[\\"onUpdate:\\" + value]: $event => (model = $event)
}, null, 16 /* FULL_PROPS */))
}), null, 16 /* FULL_PROPS */))
}
}"
`;

View File

@@ -5,11 +5,11 @@ exports[`compiler: v-once transform as root node 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, createVNode: _createVNode } = _Vue
const { setBlockTracking: _setBlockTracking, createElementVNode: _createElementVNode } = _Vue
return _cache[1] || (
_setBlockTracking(-1),
_cache[1] = _createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]),
_cache[1] = _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]),
_setBlockTracking(1),
_cache[1]
)
@@ -22,11 +22,11 @@ exports[`compiler: v-once transform on component 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { setBlockTracking: _setBlockTracking, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_cache[1] || (
_setBlockTracking(-1),
_cache[1] = _createVNode(_component_Comp, { id: foo }, null, 8 /* PROPS */, [\\"id\\"]),
@@ -43,12 +43,12 @@ exports[`compiler: v-once transform on nested plain element 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { setBlockTracking: _setBlockTracking, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_cache[1] || (
_setBlockTracking(-1),
_cache[1] = _createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]),
_cache[1] = _createElementVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]),
_setBlockTracking(1),
_cache[1]
)
@@ -62,9 +62,9 @@ exports[`compiler: v-once transform on slot outlet 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_cache[1] || (
_setBlockTracking(-1),
_cache[1] = _renderSlot($slots, \\"default\\"),
@@ -81,12 +81,12 @@ exports[`compiler: v-once transform with hoistStatic: true 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { setBlockTracking: _setBlockTracking, createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
return (_openBlock(), _createElementBlock(\\"div\\", null, [
_cache[1] || (
_setBlockTracking(-1),
_cache[1] = _createVNode(\\"div\\"),
_cache[1] = _createElementVNode(\\"div\\"),
_setBlockTracking(1),
_cache[1]
)

View File

@@ -15,14 +15,14 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots implicit default slot 1`] = `
"const { createVNode: _createVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
return (_openBlock(), _createBlock(_component_Comp, null, {
default: _withCtx(() => [
_createVNode(\\"div\\")
_createElementVNode(\\"div\\")
]),
_: 1 /* STABLE */
}))
@@ -118,7 +118,7 @@ exports[`compiler: transform component slots named slots w/ implicit default slo
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -126,7 +126,7 @@ return function render(_ctx, _cache) {
one: _withCtx(() => [\\"foo\\"]),
default: _withCtx(() => [
\\"bar\\",
_createVNode(\\"span\\")
_createElementVNode(\\"span\\")
]),
_: 1 /* STABLE */
}))
@@ -211,7 +211,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots with whitespace: 'preserve' implicit default slot 1`] = `
"const { createVNode: _createVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { createElementVNode: _createElementVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -220,7 +220,7 @@ return function render(_ctx, _cache) {
header: _withCtx(() => [\\" Header \\"]),
default: _withCtx(() => [
\\" \\",
_createVNode(\\"p\\")
_createElementVNode(\\"p\\")
]),
_: 1 /* STABLE */
}))

View File

@@ -10,7 +10,12 @@ import {
ForNode,
ConstantTypes
} from '../../src'
import { FRAGMENT, RENDER_LIST, CREATE_TEXT } from '../../src/runtimeHelpers'
import {
FRAGMENT,
RENDER_LIST,
CREATE_TEXT,
NORMALIZE_CLASS
} from '../../src/runtimeHelpers'
import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
import { transformIf } from '../../src/transforms/vIf'
@@ -510,9 +515,15 @@ describe('compiler: hoistStatic transform', () => {
constType: ConstantTypes.CAN_STRINGIFY
},
value: {
content: `{ foo: true }`,
isStatic: false,
constType: ConstantTypes.CAN_STRINGIFY
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_CLASS,
arguments: [
{
content: `{ foo: true }`,
isStatic: false,
constType: ConstantTypes.CAN_STRINGIFY
}
]
}
}
]

View File

@@ -17,7 +17,11 @@ import {
RESOLVE_DYNAMIC_COMPONENT,
SUSPENSE,
KEEP_ALIVE,
BASE_TRANSITION
BASE_TRANSITION,
NORMALIZE_CLASS,
NORMALIZE_STYLE,
NORMALIZE_PROPS,
GUARD_REACTIVE_PROPS
} from '../../src/runtimeHelpers'
import {
NodeTypes,
@@ -159,11 +163,25 @@ describe('compiler: element transform', () => {
const { root, node } = parseWithElementTransform(`<div v-bind="obj" />`)
// single v-bind doesn't need mergeProps
expect(root.helpers).not.toContain(MERGE_PROPS)
expect(root.helpers).toContain(NORMALIZE_PROPS)
expect(root.helpers).toContain(GUARD_REACTIVE_PROPS)
// should directly use `obj` in props position
expect(node.props).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION,
content: `obj`
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: GUARD_REACTIVE_PROPS,
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `obj`
}
]
}
]
})
})
@@ -655,7 +673,7 @@ describe('compiler: element transform', () => {
})
test(`props merging: style`, () => {
const { node } = parseWithElementTransform(
const { node, root } = parseWithElementTransform(
`<div style="color: green" :style="{ color: 'red' }" />`,
{
nodeTransforms: [transformStyle, transformElement],
@@ -664,6 +682,7 @@ describe('compiler: element transform', () => {
}
}
)
expect(root.helpers).toContain(NORMALIZE_STYLE)
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
@@ -675,17 +694,23 @@ describe('compiler: element transform', () => {
isStatic: true
},
value: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_STYLE,
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{"color":"green"}`,
isStatic: false
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ color: 'red' }`,
isStatic: false
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{"color":"green"}`,
isStatic: false
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ color: 'red' }`,
isStatic: false
}
]
}
]
}
@@ -695,7 +720,7 @@ describe('compiler: element transform', () => {
})
test(`props merging: class`, () => {
const { node } = parseWithElementTransform(
const { node, root } = parseWithElementTransform(
`<div class="foo" :class="{ bar: isBar }" />`,
{
directiveTransforms: {
@@ -703,6 +728,7 @@ describe('compiler: element transform', () => {
}
}
)
expect(root.helpers).toContain(NORMALIZE_CLASS)
expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
@@ -714,17 +740,23 @@ describe('compiler: element transform', () => {
isStatic: true
},
value: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_CLASS,
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `foo`,
isStatic: true
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ bar: isBar }`,
isStatic: false
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `foo`,
isStatic: true
},
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `{ bar: isBar }`,
isStatic: false
}
]
}
]
}

View File

@@ -5,11 +5,17 @@ import {
ObjectExpression,
CompilerOptions,
ErrorCodes,
VNodeCall
VNodeCall,
NodeTypes,
CallExpression
} from '../../src'
import { transformBind } from '../../src/transforms/vBind'
import { transformElement } from '../../src/transforms/transformElement'
import { CAMELIZE, helperNameMap } from '../../src/runtimeHelpers'
import {
CAMELIZE,
helperNameMap,
NORMALIZE_PROPS
} from '../../src/runtimeHelpers'
import { transformExpression } from '../../src/transforms/transformExpression'
function parseWithVBind(
@@ -68,16 +74,27 @@ describe('compiler: transform v-bind', () => {
test('dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `id || ""`,
isStatic: false
},
value: {
content: `id`,
isStatic: false
}
const props = (node.codegenNode as VNodeCall).props as CallExpression
expect(props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
{
key: {
content: `id || ""`,
isStatic: false
},
value: {
content: `id`,
isStatic: false
}
}
]
}
]
})
})
@@ -127,16 +144,27 @@ describe('compiler: transform v-bind', () => {
test('.camel modifier w/ dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `_${helperNameMap[CAMELIZE]}(foo || "")`,
isStatic: false
},
value: {
content: `id`,
isStatic: false
}
const props = (node.codegenNode as VNodeCall).props as CallExpression
expect(props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
{
key: {
content: `_${helperNameMap[CAMELIZE]}(foo || "")`,
isStatic: false
},
value: {
content: `id`,
isStatic: false
}
}
]
}
]
})
})

View File

@@ -22,6 +22,7 @@ import {
CREATE_COMMENT,
FRAGMENT,
MERGE_PROPS,
NORMALIZE_PROPS,
RENDER_SLOT
} from '../../src/runtimeHelpers'
import { createObjectMatcher } from '../testUtils'
@@ -556,8 +557,14 @@ describe('compiler: v-if', () => {
const branch1 = codegenNode.consequent as VNodeCall
expect(branch1.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS,
arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }]
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS,
arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }]
}
]
})
})

View File

@@ -9,7 +9,8 @@ import {
PlainElementNode,
ComponentNode,
NodeTypes,
VNodeCall
VNodeCall,
NORMALIZE_PROPS
} from '../../src'
import { ErrorCodes } from '../../src/errors'
import { transformModel } from '../../src/transforms/vModel'
@@ -17,6 +18,7 @@ import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression'
import { transformFor } from '../../src/transforms/vFor'
import { trackSlotScopes } from '../../src/transforms/vSlot'
import { CallExpression } from '@babel/types'
function parseWithVModel(template: string, options: CompilerOptions = {}) {
const ast = parse(template)
@@ -288,40 +290,50 @@ describe('compiler: transform v-model', () => {
test('with dynamic argument', () => {
const root = parseWithVModel('<input v-model:[value]="model" />')
const node = root.children[0] as ElementNode
const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.properties
const props = ((node.codegenNode as VNodeCall)
.props as unknown) as CallExpression
expect(props[0]).toMatchObject({
key: {
content: 'value',
isStatic: false
},
value: {
content: 'model',
isStatic: false
}
})
expect(props[1]).toMatchObject({
key: {
children: [
'"onUpdate:" + ',
{
content: 'value',
isStatic: false
}
]
},
value: {
children: [
'$event => (',
{
content: 'model',
isStatic: false
},
' = $event)'
]
}
expect(props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
{
key: {
content: 'value',
isStatic: false
},
value: {
content: 'model',
isStatic: false
}
},
{
key: {
children: [
'"onUpdate:" + ',
{
content: 'value',
isStatic: false
}
]
},
value: {
children: [
'$event => (',
{
content: 'model',
isStatic: false
},
' = $event)'
]
}
}
]
}
]
})
expect(generate(root).code).toMatchSnapshot()
@@ -332,40 +344,50 @@ describe('compiler: transform v-model', () => {
prefixIdentifiers: true
})
const node = root.children[0] as ElementNode
const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.properties
const props = ((node.codegenNode as VNodeCall)
.props as unknown) as CallExpression
expect(props[0]).toMatchObject({
key: {
content: '_ctx.value',
isStatic: false
},
value: {
content: '_ctx.model',
isStatic: false
}
})
expect(props[1]).toMatchObject({
key: {
children: [
'"onUpdate:" + ',
{
content: '_ctx.value',
isStatic: false
}
]
},
value: {
children: [
'$event => (',
{
content: '_ctx.model',
isStatic: false
},
' = $event)'
]
}
expect(props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: NORMALIZE_PROPS,
arguments: [
{
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [
{
key: {
content: '_ctx.value',
isStatic: false
},
value: {
content: '_ctx.model',
isStatic: false
}
},
{
key: {
children: [
'"onUpdate:" + ',
{
content: '_ctx.value',
isStatic: false
}
]
},
value: {
children: [
'$event => (',
{
content: '_ctx.model',
isStatic: false
},
' = $event)'
]
}
}
]
}
]
})
expect(generate(root, { mode: 'module' }).code).toMatchSnapshot()

View File

@@ -5,13 +5,12 @@ import {
CREATE_SLOTS,
RENDER_LIST,
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT,
CREATE_VNODE,
WITH_DIRECTIVES
} from './runtimeHelpers'
import { PropsExpression } from './transforms/transformElement'
import { ImportItem, TransformContext } from './transform'
import { getVNodeBlockHelper, getVNodeHelper } from './utils'
// Vue template is a platform-agnostic superset of HTML (syntax only).
// More namespaces like SVG and MathML are declared by platform specific
@@ -293,6 +292,7 @@ export interface VNodeCall extends Node {
directives: DirectiveArguments | undefined
isBlock: boolean
disableTracking: boolean
isComponent: boolean
}
// JS Node Types ---------------------------------------------------------------
@@ -560,14 +560,15 @@ export function createVNodeCall(
directives?: VNodeCall['directives'],
isBlock: VNodeCall['isBlock'] = false,
disableTracking: VNodeCall['disableTracking'] = false,
isComponent: VNodeCall['isComponent'] = false,
loc = locStub
): VNodeCall {
if (context) {
if (isBlock) {
context.helper(OPEN_BLOCK)
context.helper(CREATE_BLOCK)
context.helper(getVNodeBlockHelper(context.inSSR, isComponent))
} else {
context.helper(CREATE_VNODE)
context.helper(getVNodeHelper(context.inSSR, isComponent))
}
if (directives) {
context.helper(WITH_DIRECTIVES)
@@ -584,6 +585,7 @@ export function createVNodeCall(
directives,
isBlock,
disableTracking,
isComponent,
loc
}
}

View File

@@ -30,6 +30,8 @@ import { SourceMapGenerator, RawSourceMap } from 'source-map'
import {
advancePositionWithMutation,
assert,
getVNodeBlockHelper,
getVNodeHelper,
isSimpleIdentifier,
toValidAssetId
} from './utils'
@@ -47,7 +49,7 @@ import {
POP_SCOPE_ID,
WITH_SCOPE_ID,
WITH_DIRECTIVES,
CREATE_BLOCK,
CREATE_ELEMENT_VNODE,
OPEN_BLOCK,
CREATE_STATIC,
WITH_CTX,
@@ -96,7 +98,8 @@ function createCodegenContext(
runtimeGlobalName = `Vue`,
runtimeModuleName = `vue`,
ssr = false,
isTS = false
isTS = false,
inSSR = false
}: CodegenOptions
): CodegenContext {
const context: CodegenContext = {
@@ -110,6 +113,7 @@ function createCodegenContext(
runtimeModuleName,
ssr,
isTS,
inSSR,
source: ast.loc.source,
code: ``,
column: 1,
@@ -218,7 +222,6 @@ export function generate(
} else {
genFunctionPreamble(ast, preambleContext)
}
// enter render function
const functionName = ssr ? `ssrRender` : `render`
const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache']
@@ -355,6 +358,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
if (ast.hoists.length) {
const staticHelpers = [
CREATE_VNODE,
CREATE_ELEMENT_VNODE,
CREATE_COMMENT,
CREATE_TEXT,
CREATE_STATIC
@@ -754,7 +758,8 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
dynamicProps,
directives,
isBlock,
disableTracking
disableTracking,
isComponent
} = node
if (directives) {
push(helper(WITH_DIRECTIVES) + `(`)
@@ -765,7 +770,10 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
if (pure) {
push(PURE_ANNOTATION)
}
push(helper(isBlock ? CREATE_BLOCK : CREATE_VNODE) + `(`, node)
const callHelper: symbol = isBlock
? getVNodeBlockHelper(context.inSSR, isComponent)
: getVNodeHelper(context.inSSR, isComponent)
push(helper(callHelper) + `(`, node)
genNodeList(
genNullableArgs([tag, props, children, patchFlag, dynamicProps]),
context

View File

@@ -122,11 +122,25 @@ interface SharedTransformCodegenOptions {
*/
prefixIdentifiers?: boolean
/**
* Generate SSR-optimized render functions instead.
* Control whether generate SSR-optimized render functions instead.
* The resulting function must be attached to the component via the
* `ssrRender` option instead of `render`.
*
* When compiler generates code for SSR's fallback branch, we need to set it to false:
* - context.ssr = false
*
* see `subTransform` in `ssrTransformCompoent.ts`
*/
ssr?: boolean
/**
* Indicates whether the compiler generates code for SSR,
* it is always true when generating code for SSR,
* regardless of whether we are generating code for SSR's fallback branch,
* this means that when the compiler generates code for SSR's fallback branch:
* - context.ssr = false
* - context.inSSR = true
*/
inSSR?: boolean
/**
* Optional binding metadata analyzed from script - used to optimize
* binding access when `prefixIdentifiers` is enabled.

View File

@@ -5,7 +5,9 @@ export const KEEP_ALIVE = Symbol(__DEV__ ? `KeepAlive` : ``)
export const BASE_TRANSITION = Symbol(__DEV__ ? `BaseTransition` : ``)
export const OPEN_BLOCK = Symbol(__DEV__ ? `openBlock` : ``)
export const CREATE_BLOCK = Symbol(__DEV__ ? `createBlock` : ``)
export const CREATE_ELEMENT_BLOCK = Symbol(__DEV__ ? `createElementBlock` : ``)
export const CREATE_VNODE = Symbol(__DEV__ ? `createVNode` : ``)
export const CREATE_ELEMENT_VNODE = Symbol(__DEV__ ? `createElementVNode` : ``)
export const CREATE_COMMENT = Symbol(__DEV__ ? `createCommentVNode` : ``)
export const CREATE_TEXT = Symbol(__DEV__ ? `createTextVNode` : ``)
export const CREATE_STATIC = Symbol(__DEV__ ? `createStaticVNode` : ``)
@@ -21,6 +23,10 @@ export const RENDER_SLOT = Symbol(__DEV__ ? `renderSlot` : ``)
export const CREATE_SLOTS = Symbol(__DEV__ ? `createSlots` : ``)
export const TO_DISPLAY_STRING = Symbol(__DEV__ ? `toDisplayString` : ``)
export const MERGE_PROPS = Symbol(__DEV__ ? `mergeProps` : ``)
export const NORMALIZE_CLASS = Symbol(__DEV__ ? `normalizeClass` : ``)
export const NORMALIZE_STYLE = Symbol(__DEV__ ? `normalizeStyle` : ``)
export const NORMALIZE_PROPS = Symbol(__DEV__ ? `normalizeProps` : ``)
export const GUARD_REACTIVE_PROPS = Symbol(__DEV__ ? `guardReactiveProps` : ``)
export const TO_HANDLERS = Symbol(__DEV__ ? `toHandlers` : ``)
export const CAMELIZE = Symbol(__DEV__ ? `camelize` : ``)
export const CAPITALIZE = Symbol(__DEV__ ? `capitalize` : ``)
@@ -44,7 +50,9 @@ export const helperNameMap: any = {
[BASE_TRANSITION]: `BaseTransition`,
[OPEN_BLOCK]: `openBlock`,
[CREATE_BLOCK]: `createBlock`,
[CREATE_ELEMENT_BLOCK]: `createElementBlock`,
[CREATE_VNODE]: `createVNode`,
[CREATE_ELEMENT_VNODE]: `createElementVNode`,
[CREATE_COMMENT]: `createCommentVNode`,
[CREATE_TEXT]: `createTextVNode`,
[CREATE_STATIC]: `createStaticVNode`,
@@ -58,6 +66,10 @@ export const helperNameMap: any = {
[CREATE_SLOTS]: `createSlots`,
[TO_DISPLAY_STRING]: `toDisplayString`,
[MERGE_PROPS]: `mergeProps`,
[NORMALIZE_CLASS]: `normalizeClass`,
[NORMALIZE_STYLE]: `normalizeStyle`,
[NORMALIZE_PROPS]: `normalizeProps`,
[GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
[TO_HANDLERS]: `toHandlers`,
[CAMELIZE]: `camelize`,
[CAPITALIZE]: `capitalize`,

View File

@@ -33,12 +33,10 @@ import {
TO_DISPLAY_STRING,
FRAGMENT,
helperNameMap,
CREATE_BLOCK,
CREATE_COMMENT,
OPEN_BLOCK,
CREATE_VNODE
OPEN_BLOCK
} from './runtimeHelpers'
import { isVSlot } from './utils'
import { getVNodeBlockHelper, getVNodeHelper, isVSlot } from './utils'
import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic'
import { CompilerCompatOptions } from './compat/compatConfig'
@@ -139,6 +137,7 @@ export function createTransformContext(
scopeId = null,
slotted = true,
ssr = false,
inSSR = false,
ssrCssVars = ``,
bindingMetadata = EMPTY_OBJ,
inline = false,
@@ -164,6 +163,7 @@ export function createTransformContext(
scopeId,
slotted,
ssr,
inSSR,
ssrCssVars,
bindingMetadata,
inline,
@@ -346,10 +346,10 @@ function createRootCodegen(root: RootNode, context: TransformContext) {
const codegenNode = child.codegenNode
if (codegenNode.type === NodeTypes.VNODE_CALL) {
if (!codegenNode.isBlock) {
removeHelper(CREATE_VNODE)
codegenNode.isBlock = true
removeHelper(getVNodeHelper(context.inSSR, codegenNode.isComponent))
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)
helper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent))
}
}
root.codegenNode = codegenNode
@@ -380,7 +380,9 @@ function createRootCodegen(root: RootNode, context: TransformContext) {
patchFlag + (__DEV__ ? ` /* ${patchFlagText} */` : ``),
undefined,
undefined,
true
true,
undefined,
false /* isComponent */
)
} else {
// no children = noop. codegen will return null.

View File

@@ -9,12 +9,20 @@ import {
ComponentNode,
TemplateNode,
VNodeCall,
ParentNode
ParentNode,
JSChildNode,
CallExpression
} from '../ast'
import { TransformContext } from '../transform'
import { PatchFlags, isString, isSymbol } from '@vue/shared'
import { isSlotOutlet } from '../utils'
import { CREATE_BLOCK, CREATE_VNODE, OPEN_BLOCK } from '../runtimeHelpers'
import { getVNodeBlockHelper, getVNodeHelper, isSlotOutlet } from '../utils'
import {
OPEN_BLOCK,
GUARD_REACTIVE_PROPS,
NORMALIZE_CLASS,
NORMALIZE_PROPS,
NORMALIZE_STYLE
} from '../runtimeHelpers'
export function hoistStatic(root: RootNode, context: TransformContext) {
walk(
@@ -213,9 +221,11 @@ export function getConstantType(
// nested updates.
if (codegenNode.isBlock) {
context.removeHelper(OPEN_BLOCK)
context.removeHelper(CREATE_BLOCK)
context.removeHelper(
getVNodeBlockHelper(context.inSSR, codegenNode.isComponent)
)
codegenNode.isBlock = false
context.helper(CREATE_VNODE)
context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent))
}
constantCache.set(node, returnType)
@@ -260,6 +270,33 @@ export function getConstantType(
}
}
const allowHoistedHelperSet = new Set([
NORMALIZE_CLASS,
NORMALIZE_STYLE,
NORMALIZE_PROPS,
GUARD_REACTIVE_PROPS
])
function getConstantTypeOfHelperCall(
value: CallExpression,
context: TransformContext
): ConstantTypes {
if (
value.type === NodeTypes.JS_CALL_EXPRESSION &&
!isString(value.callee) &&
allowHoistedHelperSet.has(value.callee)
) {
const arg = value.arguments[0] as JSChildNode
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
return getConstantType(arg, context)
} else if (arg.type === NodeTypes.JS_CALL_EXPRESSION) {
// in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
return getConstantTypeOfHelperCall(arg, context)
}
}
return ConstantTypes.NOT_CONSTANT
}
function getGeneratedPropsConstantType(
node: PlainElementNode,
context: TransformContext
@@ -278,6 +315,12 @@ function getGeneratedPropsConstantType(
returnType = keyType
}
if (value.type !== NodeTypes.SIMPLE_EXPRESSION) {
// some helper calls can be hoisted,
// such as the `normalizeProps` generated by the compiler for pre-normalize class,
// in this case we need to respect the ConstanType of the helper's argments
if (value.type === NodeTypes.JS_CALL_EXPRESSION) {
return getConstantTypeOfHelperCall(value, context)
}
return ConstantTypes.NOT_CONSTANT
}
const valueType = getConstantType(value, context)

View File

@@ -37,11 +37,15 @@ import {
RESOLVE_COMPONENT,
RESOLVE_DYNAMIC_COMPONENT,
MERGE_PROPS,
NORMALIZE_CLASS,
NORMALIZE_STYLE,
NORMALIZE_PROPS,
TO_HANDLERS,
TELEPORT,
KEEP_ALIVE,
SUSPENSE,
UNREF
UNREF,
GUARD_REACTIVE_PROPS
} from '../runtimeHelpers'
import {
getInnerRange,
@@ -226,6 +230,7 @@ export const transformElement: NodeTransform = (node, context) => {
vnodeDirectives,
!!shouldUseBlock,
false /* disableTracking */,
isComponent,
node.loc
)
}
@@ -418,15 +423,25 @@ export function buildProps(
// skip if the prop is a cached handler or has constant value
return
}
if (name === 'ref') {
hasRef = true
} else if (name === 'class' && !isComponent) {
} else if (name === 'class') {
hasClassBinding = true
} else if (name === 'style' && !isComponent) {
} else if (name === 'style') {
hasStyleBinding = true
} else if (name !== 'key' && !dynamicPropNames.includes(name)) {
dynamicPropNames.push(name)
}
// treat the dynamic class and style binding of the component as dynamic props
if (
isComponent &&
(name === 'class' || name === 'style') &&
!dynamicPropNames.includes(name)
) {
dynamicPropNames.push(name)
}
} else {
hasDynamicKeys = true
}
@@ -657,10 +672,10 @@ export function buildProps(
if (hasDynamicKeys) {
patchFlag |= PatchFlags.FULL_PROPS
} else {
if (hasClassBinding) {
if (hasClassBinding && !isComponent) {
patchFlag |= PatchFlags.CLASS
}
if (hasStyleBinding) {
if (hasStyleBinding && !isComponent) {
patchFlag |= PatchFlags.STYLE
}
if (dynamicPropNames.length) {
@@ -677,6 +692,72 @@ export function buildProps(
patchFlag |= PatchFlags.NEED_PATCH
}
// pre-normalize props, SSR is skipped for now
if (!context.inSSR && propsExpression) {
switch (propsExpression.type) {
case NodeTypes.JS_OBJECT_EXPRESSION:
// means that there is no v-bind,
// but still need to deal with dynamic key binding
let classKeyIndex = -1
let styleKeyIndex = -1
let dynamicKeyIndex = -1
for (let i = 0; i < propsExpression.properties.length; i++) {
const p = propsExpression.properties[i]
if (p.key.type !== NodeTypes.SIMPLE_EXPRESSION) continue
if (!isStaticExp(p.key)) dynamicKeyIndex = i
if (isStaticExp(p.key) && p.key.content === 'class') classKeyIndex = i
if (isStaticExp(p.key) && p.key.content === 'style') styleKeyIndex = i
}
const classProp = propsExpression.properties[classKeyIndex]
const styleProp = propsExpression.properties[styleKeyIndex]
// no dynamic key
if (dynamicKeyIndex === -1) {
if (classProp && !isStaticExp(classProp.value)) {
classProp.value = createCallExpression(
context.helper(NORMALIZE_CLASS),
[classProp.value]
)
}
if (
styleProp &&
!isStaticExp(styleProp.value) &&
// the static style is compiled into an object,
// so use `hasStyleBinding` to ensure that it is a dynamic style binding
hasStyleBinding
) {
styleProp.value = createCallExpression(
context.helper(NORMALIZE_STYLE),
[styleProp.value]
)
}
} else {
// dynamic key binding, wrap with `normalizeProps`
propsExpression = createCallExpression(
context.helper(NORMALIZE_PROPS),
[propsExpression]
)
}
break
case NodeTypes.JS_CALL_EXPRESSION:
// mergeProps call, do nothing
break
default:
// single v-bind
propsExpression = createCallExpression(
context.helper(NORMALIZE_PROPS),
[
createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
propsExpression
])
]
)
break
}
}
return {
props: propsExpression,
directives: runtimeDirectives,

View File

@@ -32,15 +32,11 @@ import {
findProp,
isTemplateNode,
isSlotOutlet,
injectProp
injectProp,
getVNodeBlockHelper,
getVNodeHelper
} from '../utils'
import {
RENDER_LIST,
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT,
CREATE_VNODE
} from '../runtimeHelpers'
import { RENDER_LIST, OPEN_BLOCK, FRAGMENT } from '../runtimeHelpers'
import { processExpression } from './transformExpression'
import { validateBrowserExpression } from '../validateExpression'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
@@ -85,6 +81,7 @@ export const transformFor = createStructuralDirectiveTransform(
: keyProp
? PatchFlags.KEYED_FRAGMENT
: PatchFlags.UNKEYED_FRAGMENT
forNode.codegenNode = createVNodeCall(
context,
helper(FRAGMENT),
@@ -96,6 +93,7 @@ export const transformFor = createStructuralDirectiveTransform(
undefined,
true /* isBlock */,
!isStableFragment /* disableTracking */,
false /* isComponent */,
node.loc
) as ForCodegenNode
@@ -156,7 +154,9 @@ export const transformFor = createStructuralDirectiveTransform(
: ``),
undefined,
undefined,
true
true,
undefined,
false /* isComponent */
)
} else {
// Normal element v-for. Directly use the child's codegenNode
@@ -170,18 +170,22 @@ export const transformFor = createStructuralDirectiveTransform(
if (childBlock.isBlock) {
// switch from block to vnode
removeHelper(OPEN_BLOCK)
removeHelper(CREATE_BLOCK)
removeHelper(
getVNodeBlockHelper(context.inSSR, childBlock.isComponent)
)
} else {
// switch from vnode to block
removeHelper(CREATE_VNODE)
removeHelper(
getVNodeHelper(context.inSSR, childBlock.isComponent)
)
}
}
childBlock.isBlock = !isStableFragment
if (childBlock.isBlock) {
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)
helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent))
} else {
helper(CREATE_VNODE)
helper(getVNodeHelper(context.inSSR, childBlock.isComponent))
}
}

View File

@@ -27,14 +27,15 @@ import {
import { createCompilerError, ErrorCodes } from '../errors'
import { processExpression } from './transformExpression'
import { validateBrowserExpression } from '../validateExpression'
import { FRAGMENT, CREATE_COMMENT, OPEN_BLOCK } from '../runtimeHelpers'
import {
CREATE_BLOCK,
FRAGMENT,
CREATE_COMMENT,
OPEN_BLOCK,
CREATE_VNODE
} from '../runtimeHelpers'
import { injectProp, findDir, findProp, isBuiltInType } from '../utils'
injectProp,
findDir,
findProp,
isBuiltInType,
getVNodeHelper,
getVNodeBlockHelper
} from '../utils'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
export const transformIf = createStructuralDirectiveTransform(
@@ -278,6 +279,7 @@ function createChildrenCodegenNode(
undefined,
true,
false,
false /* isComponent */,
branch.loc
)
}
@@ -286,10 +288,10 @@ function createChildrenCodegenNode(
.codegenNode as BlockCodegenNode
// Change createVNode to createBlock.
if (vnodeCall.type === NodeTypes.VNODE_CALL && !vnodeCall.isBlock) {
removeHelper(CREATE_VNODE)
removeHelper(getVNodeHelper(context.inSSR, vnodeCall.isComponent))
vnodeCall.isBlock = true
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)
helper(getVNodeBlockHelper(context.inSSR, vnodeCall.isComponent))
}
// inject branch key
injectProp(vnodeCall, keyProperty, context)

View File

@@ -30,9 +30,16 @@ import {
SUSPENSE,
KEEP_ALIVE,
BASE_TRANSITION,
TO_HANDLERS
TO_HANDLERS,
NORMALIZE_PROPS,
GUARD_REACTIVE_PROPS,
CREATE_BLOCK,
CREATE_ELEMENT_BLOCK,
CREATE_VNODE,
CREATE_ELEMENT_VNODE
} from './runtimeHelpers'
import { isString, isObject, hyphenate, extend } from '@vue/shared'
import { PropsExpression } from './transforms/transformElement'
export const isStaticExp = (p: JSChildNode): p is SimpleExpressionNode =>
p.type === NodeTypes.SIMPLE_EXPRESSION && p.isStatic
@@ -291,14 +298,66 @@ export function isSlotOutlet(
return node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.SLOT
}
export function getVNodeHelper(ssr: boolean, isComponent: boolean) {
return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE
}
export function getVNodeBlockHelper(ssr: boolean, isComponent: boolean) {
return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK
}
const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS])
function getUnnormalizedProps(
props: PropsExpression | '{}',
callPath: CallExpression[] = []
): [PropsExpression | '{}', CallExpression[]] {
if (
props &&
!isString(props) &&
props.type === NodeTypes.JS_CALL_EXPRESSION
) {
const callee = props.callee
if (!isString(callee) && propsHelperSet.has(callee)) {
return getUnnormalizedProps(
props.arguments[0] as PropsExpression,
callPath.concat(props)
)
}
}
return [props, callPath]
}
export function injectProp(
node: VNodeCall | RenderSlotCall,
prop: Property,
context: TransformContext
) {
let propsWithInjection: ObjectExpression | CallExpression | undefined
const props =
const originalProps =
node.type === NodeTypes.VNODE_CALL ? node.props : node.arguments[2]
/**
* 1. mergeProps(...)
* 2. toHandlers(...)
* 3. normalizeProps(...)
* 4. normalizeProps(guardReactiveProps(...))
*
* we need to get the real props before normalization
*/
let props = originalProps
let callPath: CallExpression[] = []
let parentCall: CallExpression | undefined
if (
props &&
!isString(props) &&
props.type === NodeTypes.JS_CALL_EXPRESSION
) {
const ret = getUnnormalizedProps(props)
props = ret[0]
callPath = ret[1]
parentCall = callPath[callPath.length - 1]
}
if (props == null || isString(props)) {
propsWithInjection = createObjectExpression([prop])
} else if (props.type === NodeTypes.JS_CALL_EXPRESSION) {
@@ -341,11 +400,25 @@ export function injectProp(
createObjectExpression([prop]),
props
])
// in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
// it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
// the `guardReactiveProps` will no longer be needed
if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
parentCall = callPath[callPath.length - 2]
}
}
if (node.type === NodeTypes.VNODE_CALL) {
node.props = propsWithInjection
if (parentCall) {
parentCall.arguments[0] = propsWithInjection
} else {
node.props = propsWithInjection
}
} else {
node.arguments[2] = propsWithInjection
if (parentCall) {
parentCall.arguments[0] = propsWithInjection
} else {
node.arguments[2] = propsWithInjection
}
}
}