feat(compiler): generate patchFlags for runtime
This commit is contained in:
@@ -11,14 +11,14 @@ return function render() {
|
||||
}, [
|
||||
_toString(world.burn()),
|
||||
ok
|
||||
? _createVNode(\\"div\\", 0, \\"yes\\")
|
||||
? _createVNode(\\"div\\", null, \\"yes\\")
|
||||
: \\"no\\",
|
||||
_renderList(list, (value, index) => {
|
||||
return _createVNode(\\"div\\", 0, [
|
||||
_createVNode(\\"span\\", 0, _toString(value + index))
|
||||
return _createVNode(\\"div\\", null, [
|
||||
_createVNode(\\"span\\", null, _toString(value + index))
|
||||
])
|
||||
})
|
||||
])
|
||||
], 2)
|
||||
}
|
||||
}"
|
||||
`;
|
||||
@@ -34,14 +34,14 @@ return function render() {
|
||||
}, [
|
||||
toString(_ctx.world.burn()),
|
||||
(_ctx.ok)
|
||||
? createVNode(\\"div\\", 0, \\"yes\\")
|
||||
? createVNode(\\"div\\", null, \\"yes\\")
|
||||
: \\"no\\",
|
||||
renderList(_ctx.list, (value, index) => {
|
||||
return createVNode(\\"div\\", 0, [
|
||||
createVNode(\\"span\\", 0, toString(value + index))
|
||||
return createVNode(\\"div\\", null, [
|
||||
createVNode(\\"span\\", null, toString(value + index))
|
||||
])
|
||||
})
|
||||
])
|
||||
], 2)
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -56,13 +56,13 @@ export default function render() {
|
||||
}, [
|
||||
_toString(_ctx.world.burn()),
|
||||
(_ctx.ok)
|
||||
? createVNode(\\"div\\", 0, \\"yes\\")
|
||||
? createVNode(\\"div\\", null, \\"yes\\")
|
||||
: \\"no\\",
|
||||
_renderList(_ctx.list, (value, index) => {
|
||||
return createVNode(\\"div\\", 0, [
|
||||
createVNode(\\"span\\", 0, _toString(value + index))
|
||||
return createVNode(\\"div\\", null, [
|
||||
createVNode(\\"span\\", null, _toString(value + index))
|
||||
])
|
||||
})
|
||||
])
|
||||
], 2)
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -7,7 +7,7 @@ return function render() {
|
||||
const _ctx = this
|
||||
const _component_Comp = resolveComponent(\\"Comp\\")
|
||||
|
||||
return createVNode(_component_Comp, 0, {
|
||||
return createVNode(_component_Comp, null, {
|
||||
[_ctx.one]: ({ foo }) => [
|
||||
toString(foo),
|
||||
toString(_ctx.bar)
|
||||
@@ -16,7 +16,7 @@ return function render() {
|
||||
toString(_ctx.foo),
|
||||
toString(bar)
|
||||
]
|
||||
})
|
||||
}, 256)
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -27,7 +27,7 @@ return function render() {
|
||||
const _ctx = this
|
||||
const _component_Comp = resolveComponent(\\"Comp\\")
|
||||
|
||||
return createVNode(_component_Comp, 0, {
|
||||
return createVNode(_component_Comp, null, {
|
||||
default: ({ foo }) => [
|
||||
toString(foo),
|
||||
toString(_ctx.bar)
|
||||
@@ -43,7 +43,7 @@ return function render() {
|
||||
const _ctx = this
|
||||
const _component_Comp = resolveComponent(\\"Comp\\")
|
||||
|
||||
return createVNode(_component_Comp, 0, {
|
||||
return createVNode(_component_Comp, null, {
|
||||
default: () => [
|
||||
createVNode(\\"div\\")
|
||||
]
|
||||
@@ -58,7 +58,7 @@ return function render() {
|
||||
const _ctx = this
|
||||
const _component_Comp = resolveComponent(\\"Comp\\")
|
||||
|
||||
return createVNode(_component_Comp, 0, {
|
||||
return createVNode(_component_Comp, null, {
|
||||
one: ({ foo }) => [
|
||||
toString(foo),
|
||||
toString(_ctx.bar)
|
||||
@@ -79,9 +79,9 @@ return function render() {
|
||||
const _component_Comp = resolveComponent(\\"Comp\\")
|
||||
const _component_Inner = resolveComponent(\\"Inner\\")
|
||||
|
||||
return createVNode(_component_Comp, 0, {
|
||||
return createVNode(_component_Comp, null, {
|
||||
default: ({ foo }) => [
|
||||
createVNode(_component_Inner, 0, {
|
||||
createVNode(_component_Inner, null, {
|
||||
default: ({ bar }) => [
|
||||
toString(foo),
|
||||
toString(bar),
|
||||
|
||||
@@ -24,6 +24,7 @@ import { transformElement } from '../../src/transforms/transformElement'
|
||||
import { transformOn } from '../../src/transforms/vOn'
|
||||
import { transformStyle } from '../../src/transforms/transformStyle'
|
||||
import { transformBind } from '../../src/transforms/vBind'
|
||||
import { PatchFlags } from '@vue/shared'
|
||||
|
||||
function parseWithElementTransform(
|
||||
template: string,
|
||||
@@ -127,7 +128,7 @@ describe('compiler: element transform', () => {
|
||||
expect(node.callee).toBe(`_${CREATE_VNODE}`)
|
||||
expect(node.arguments).toMatchObject([
|
||||
`"div"`,
|
||||
`0`,
|
||||
`null`,
|
||||
[
|
||||
{
|
||||
type: NodeTypes.ELEMENT,
|
||||
@@ -351,7 +352,9 @@ describe('compiler: element transform', () => {
|
||||
value: _dir!.exp
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
`null`,
|
||||
String(PatchFlags.NEED_PATCH) // should generate appropriate flag
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -546,5 +549,121 @@ describe('compiler: element transform', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test.todo('slot outlets')
|
||||
test(`props merging: class`, () => {
|
||||
const { node } = parseWithElementTransform(
|
||||
`<div class="foo" :class="{ bar: isBar }" />`,
|
||||
{
|
||||
directiveTransforms: {
|
||||
bind: transformBind
|
||||
}
|
||||
}
|
||||
)
|
||||
expect(node.arguments[1]).toMatchObject({
|
||||
type: NodeTypes.JS_OBJECT_EXPRESSION,
|
||||
properties: [
|
||||
{
|
||||
type: NodeTypes.JS_PROPERTY,
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: `class`,
|
||||
isStatic: true
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
||||
elements: [
|
||||
{
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: `foo`,
|
||||
isStatic: true
|
||||
},
|
||||
{
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: `{ bar: isBar }`,
|
||||
isStatic: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
describe('patchFlag analysis', () => {
|
||||
function parseWithBind(template: string) {
|
||||
return parseWithElementTransform(template, {
|
||||
directiveTransforms: {
|
||||
bind: transformBind
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
test('CLASS', () => {
|
||||
const { node } = parseWithBind(`<div :class="foo" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.CLASS))
|
||||
})
|
||||
|
||||
test('STYLE', () => {
|
||||
const { node } = parseWithBind(`<div :style="foo" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.STYLE))
|
||||
})
|
||||
|
||||
test('PROPS', () => {
|
||||
const { node } = parseWithBind(`<div id="foo" :foo="bar" :baz="qux" />`)
|
||||
expect(node.arguments.length).toBe(5)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.PROPS))
|
||||
expect(node.arguments[4]).toBe(`["foo", "baz"]`)
|
||||
})
|
||||
|
||||
test('CLASS + STYLE + PROPS', () => {
|
||||
const { node } = parseWithBind(
|
||||
`<div id="foo" :class="cls" :style="styl" :foo="bar" :baz="qux"/>`
|
||||
)
|
||||
expect(node.arguments.length).toBe(5)
|
||||
expect(node.arguments[3]).toBe(
|
||||
String(PatchFlags.PROPS | PatchFlags.CLASS | PatchFlags.STYLE)
|
||||
)
|
||||
expect(node.arguments[4]).toBe(`["foo", "baz"]`)
|
||||
})
|
||||
|
||||
test('FULL_PROPS (v-bind)', () => {
|
||||
const { node } = parseWithBind(`<div v-bind="foo" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS))
|
||||
})
|
||||
|
||||
test('FULL_PROPS (dynamic key)', () => {
|
||||
const { node } = parseWithBind(`<div :[foo]="bar" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS))
|
||||
})
|
||||
|
||||
test('FULL_PROPS (w/ others)', () => {
|
||||
const { node } = parseWithBind(
|
||||
`<div id="foo" v-bind="bar" :class="cls" />`
|
||||
)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS))
|
||||
})
|
||||
|
||||
test('NEED_PATCH (static ref)', () => {
|
||||
const { node } = parseWithBind(`<div ref="foo" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.NEED_PATCH))
|
||||
})
|
||||
|
||||
test('NEED_PATCH (dynamic ref)', () => {
|
||||
const { node } = parseWithBind(`<div :ref="foo" />`)
|
||||
expect(node.arguments.length).toBe(4)
|
||||
expect(node.arguments[3]).toBe(String(PatchFlags.NEED_PATCH))
|
||||
})
|
||||
|
||||
test('NEED_PATCH (custom directives)', () => {
|
||||
const { node } = parseWithBind(`<div v-foo />`)
|
||||
const vnodeCall = node.arguments[0] as CallExpression
|
||||
expect(vnodeCall.arguments.length).toBe(4)
|
||||
expect(vnodeCall.arguments[3]).toBe(String(PatchFlags.NEED_PATCH))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -260,7 +260,7 @@ describe('compiler: transform component slots', () => {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
arguments: [
|
||||
`_component_Inner`,
|
||||
`0`,
|
||||
`null`,
|
||||
createSlotMatcher({
|
||||
default: {
|
||||
type: NodeTypes.JS_SLOT_FUNCTION,
|
||||
|
||||
Reference in New Issue
Block a user