mirror of https://github.com/vuejs/core.git
wip: v-for destructure expression rewrite (part 1)
This commit is contained in:
parent
e49c5a17da
commit
fca1aef896
|
@ -1,15 +1,15 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`compiler: v-for > array de-structured value 1`] = `
|
exports[`compiler: v-for > array de-structured value 1`] = `
|
||||||
"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue';
|
"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
|
||||||
const t0 = _template("<div></div>", true)
|
const t0 = _template("<div></div>", true)
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = _createFor(() => (_ctx.list), _withDestructure(([[id, ...other], index]) => [id, other, index], (_ctx0) => {
|
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
|
||||||
const n2 = t0()
|
const n2 = t0()
|
||||||
_renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2]))
|
_renderEffect(() => _setText(n2, _ctx0[0].value[0] + _ctx0[0].value[1] + _ctx0[1].value))
|
||||||
return n2
|
return n2
|
||||||
}), ([id, ...other], index) => (id))
|
}, ([id, other], index) => (id))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
@ -73,7 +73,7 @@ export function render(_ctx) {
|
||||||
const n4 = t0()
|
const n4 = t0()
|
||||||
_renderEffect(() => _setText(n4, _ctx1[0].value+_ctx0[0].value))
|
_renderEffect(() => _setText(n4, _ctx1[0].value+_ctx0[0].value))
|
||||||
return n4
|
return n4
|
||||||
}, null, n5)
|
})
|
||||||
_insert(n2, n5)
|
_insert(n2, n5)
|
||||||
return n5
|
return n5
|
||||||
})
|
})
|
||||||
|
@ -81,16 +81,44 @@ export function render(_ctx) {
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: v-for > object de-structured value 1`] = `
|
exports[`compiler: v-for > object de-structured value (with rest) 1`] = `
|
||||||
"import { setText as _setText, renderEffect as _renderEffect, withDestructure as _withDestructure, createFor as _createFor, template as _template } from 'vue';
|
"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
|
||||||
const t0 = _template("<div></div>", true)
|
const t0 = _template("<div></div>", true)
|
||||||
|
|
||||||
export function render(_ctx) {
|
export function render(_ctx) {
|
||||||
const n0 = _createFor(() => (_ctx.list), _withDestructure(([{ id, ...other }, index]) => [id, other, index], (_ctx0) => {
|
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
|
||||||
const n2 = t0()
|
const n2 = t0()
|
||||||
_renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2]))
|
_renderEffect(() => _setText(n2, _ctx0[0].value.id + _ctx0[0].value + _ctx0[1].value))
|
||||||
return n2
|
return n2
|
||||||
}), ({ id, ...other }, index) => (id))
|
}, ({ id, ...other }, index) => (id))
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: v-for > object de-structured value 1`] = `
|
||||||
|
"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
|
||||||
|
const t0 = _template("<span></span>", true)
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const n0 = _createFor(() => (_ctx.items), (_ctx0) => {
|
||||||
|
const n2 = t0()
|
||||||
|
_renderEffect(() => _setText(n2, _ctx0[0].value.id, _ctx0[0].value.value))
|
||||||
|
return n2
|
||||||
|
}, ({ id, value }) => (id))
|
||||||
|
return n0
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`compiler: v-for > object de-structured value 2`] = `
|
||||||
|
"import { setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
|
||||||
|
const t0 = _template("<div></div>", true)
|
||||||
|
|
||||||
|
export function render(_ctx) {
|
||||||
|
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
|
||||||
|
const n2 = t0()
|
||||||
|
_renderEffect(() => _setText(n2, _ctx0[0].value.id + _ctx0[0].value + _ctx0[1].value))
|
||||||
|
return n2
|
||||||
|
}, ({ id, ...other }, index) => (id))
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function render(_ctx) {
|
||||||
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
|
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
|
||||||
const n2 = t0()
|
const n2 = t0()
|
||||||
return n2
|
return n2
|
||||||
}, null, null, null, true)
|
}, null, null, true)
|
||||||
return n0
|
return n0
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -79,13 +79,6 @@ describe('compiler: v-for', () => {
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
test.todo('object de-structured value', () => {
|
|
||||||
const { code } = compileWithVFor(
|
|
||||||
'<span v-for="({ id, value }) in items">{{ id }}{{ value }}</span>',
|
|
||||||
)
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('nested v-for', () => {
|
test('nested v-for', () => {
|
||||||
const { code, ir } = compileWithVFor(
|
const { code, ir } = compileWithVFor(
|
||||||
`<div v-for="i in list"><span v-for="j in i">{{ j+i }}</span></div>`,
|
`<div v-for="i in list"><span v-for="j in i">{{ j+i }}</span></div>`,
|
||||||
|
@ -124,12 +117,38 @@ describe('compiler: v-for', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('object de-structured value', () => {
|
test('object de-structured value', () => {
|
||||||
|
const { code, ir } = compileWithVFor(
|
||||||
|
'<span v-for="({ id, value }) in items" :key="id">{{ id }}{{ value }}</span>',
|
||||||
|
)
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(ir.block.operation[0]).toMatchObject({
|
||||||
|
type: IRNodeTypes.FOR,
|
||||||
|
source: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: 'items',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: '{ id, value }',
|
||||||
|
ast: {
|
||||||
|
type: 'ArrowFunctionExpression',
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
type: 'ObjectPattern',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
key: undefined,
|
||||||
|
index: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test.todo('object de-structured value (with rest)', () => {
|
||||||
const { code, ir } = compileWithVFor(
|
const { code, ir } = compileWithVFor(
|
||||||
`<div v-for="( { id, ...other }, index) in list" :key="id">{{ id + other + index }}</div>`,
|
`<div v-for="( { id, ...other }, index) in list" :key="id">{{ id + other + index }}</div>`,
|
||||||
)
|
)
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(`([{ id, ...other }, index]) => [id, other, index]`)
|
|
||||||
expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`)
|
|
||||||
expect(ir.block.operation[0]).toMatchObject({
|
expect(ir.block.operation[0]).toMatchObject({
|
||||||
type: IRNodeTypes.FOR,
|
type: IRNodeTypes.FOR,
|
||||||
source: {
|
source: {
|
||||||
|
@ -157,12 +176,41 @@ describe('compiler: v-for', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('array de-structured value', () => {
|
test('array de-structured value', () => {
|
||||||
|
const { code, ir } = compileWithVFor(
|
||||||
|
`<div v-for="([id, other], index) in list" :key="id">{{ id + other + index }}</div>`,
|
||||||
|
)
|
||||||
|
expect(code).matchSnapshot()
|
||||||
|
expect(ir.block.operation[0]).toMatchObject({
|
||||||
|
type: IRNodeTypes.FOR,
|
||||||
|
source: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: 'list',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: '[id, other]',
|
||||||
|
ast: {
|
||||||
|
type: 'ArrowFunctionExpression',
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
type: 'ArrayPattern',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
key: {
|
||||||
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||||
|
content: 'index',
|
||||||
|
},
|
||||||
|
index: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test.todo('array de-structured value (with rest)', () => {
|
||||||
const { code, ir } = compileWithVFor(
|
const { code, ir } = compileWithVFor(
|
||||||
`<div v-for="([id, ...other], index) in list" :key="id">{{ id + other + index }}</div>`,
|
`<div v-for="([id, ...other], index) in list" :key="id">{{ id + other + index }}</div>`,
|
||||||
)
|
)
|
||||||
expect(code).matchSnapshot()
|
expect(code).matchSnapshot()
|
||||||
expect(code).contains(`([[id, ...other], index]) => [id, other, index]`)
|
|
||||||
expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`)
|
|
||||||
expect(ir.block.operation[0]).toMatchObject({
|
expect(ir.block.operation[0]).toMatchObject({
|
||||||
type: IRNodeTypes.FOR,
|
type: IRNodeTypes.FOR,
|
||||||
source: {
|
source: {
|
||||||
|
@ -189,7 +237,7 @@ describe('compiler: v-for', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-for aliases w/ complex expressions', () => {
|
test.todo('v-for aliases w/ complex expressions', () => {
|
||||||
const { code, ir } = compileWithVFor(
|
const { code, ir } = compileWithVFor(
|
||||||
`<div v-for="({ foo = bar, baz: [qux = quux] }) in list">
|
`<div v-for="({ foo = bar, baz: [qux = quux] }) in list">
|
||||||
{{ foo + bar + baz + qux + quux }}
|
{{ foo + bar + baz + qux + quux }}
|
||||||
|
@ -222,17 +270,4 @@ describe('compiler: v-for', () => {
|
||||||
index: undefined,
|
index: undefined,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('function params w/ prefixIdentifiers: false', () => {
|
|
||||||
const { code } = compileWithVFor(
|
|
||||||
`<div v-for="(item, , k) of items" :key="k">{{ item }}</div>`,
|
|
||||||
{
|
|
||||||
prefixIdentifiers: false,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(code).contains(`_createFor(() => (items), ([item, __, k]) => {`)
|
|
||||||
expect(code).contain(`_setText(n2, item)`)
|
|
||||||
expect(code).matchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,56 +3,39 @@ import { genBlock } from './block'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import type { CodegenContext } from '../generate'
|
import type { CodegenContext } from '../generate'
|
||||||
import type { ForIRNode } from '../ir'
|
import type { ForIRNode } from '../ir'
|
||||||
import {
|
import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils'
|
||||||
type CodeFragment,
|
import type { Identifier } from '@babel/types'
|
||||||
DELIMITERS_ARRAY,
|
|
||||||
NEWLINE,
|
|
||||||
genCall,
|
|
||||||
genMulti,
|
|
||||||
} from './utils'
|
|
||||||
|
|
||||||
export function genFor(
|
export function genFor(
|
||||||
oper: ForIRNode,
|
oper: ForIRNode,
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
const { helper } = context
|
const { helper } = context
|
||||||
const { source, value, key, index, render, keyProp, once, id, container } =
|
const { source, value, key, index, render, keyProp, once, id, component } =
|
||||||
oper
|
oper
|
||||||
|
|
||||||
let isDestructure = false
|
|
||||||
let rawValue: string | null = null
|
let rawValue: string | null = null
|
||||||
const rawKey = key && key.content
|
const rawKey = key && key.content
|
||||||
const rawIndex = index && index.content
|
const rawIndex = index && index.content
|
||||||
|
|
||||||
const sourceExpr = ['() => (', ...genExpression(source, context), ')']
|
const sourceExpr = ['() => (', ...genExpression(source, context), ')']
|
||||||
const idsInValue = getIdsInValue()
|
const idToPathMap = parseValueDestructure()
|
||||||
let blockFn = genBlockFn()
|
|
||||||
const simpleIdMap: Record<string, null> = genSimpleIdMap()
|
|
||||||
|
|
||||||
if (isDestructure) {
|
const [depth, exitScope] = context.enterScope()
|
||||||
const idMap: Record<string, null> = {}
|
const propsName = `_ctx${depth}`
|
||||||
idsInValue.forEach(id => (idMap[id] = null))
|
const idMap: Record<string, string | null> = {}
|
||||||
if (rawKey) idMap[rawKey] = null
|
|
||||||
if (rawIndex) idMap[rawIndex] = null
|
|
||||||
const destructureAssignmentFn: CodeFragment[] = [
|
|
||||||
'(',
|
|
||||||
...genMulti(
|
|
||||||
DELIMITERS_ARRAY,
|
|
||||||
rawValue ? rawValue : rawKey || rawIndex ? '_' : undefined,
|
|
||||||
rawKey ? rawKey : rawIndex ? '__' : undefined,
|
|
||||||
rawIndex,
|
|
||||||
),
|
|
||||||
') => ',
|
|
||||||
...genMulti(DELIMITERS_ARRAY, ...idsInValue, rawKey, rawIndex),
|
|
||||||
]
|
|
||||||
|
|
||||||
blockFn = genCall(
|
idToPathMap.forEach((path, id) => {
|
||||||
// @ts-expect-error
|
idMap[id] = `${propsName}[0].value${path}`
|
||||||
helper('withDestructure'),
|
})
|
||||||
destructureAssignmentFn,
|
if (rawKey) idMap[rawKey] = `${propsName}[1].value`
|
||||||
blockFn,
|
if (rawIndex) idMap[rawIndex] = `${propsName}[2].value`
|
||||||
)
|
|
||||||
}
|
const blockFn = context.withId(
|
||||||
|
() => genBlock(render, context, [propsName]),
|
||||||
|
idMap,
|
||||||
|
)
|
||||||
|
exitScope()
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
|
@ -62,67 +45,68 @@ export function genFor(
|
||||||
sourceExpr,
|
sourceExpr,
|
||||||
blockFn,
|
blockFn,
|
||||||
genCallback(keyProp),
|
genCallback(keyProp),
|
||||||
container != null && `n${container}`,
|
component && 'true',
|
||||||
false, // todo: hydrationNode
|
|
||||||
once && 'true',
|
once && 'true',
|
||||||
|
// todo: hydrationNode
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
function getIdsInValue() {
|
// construct a id -> accessor path map.
|
||||||
const idsInValue = new Set<string>()
|
// e.g. `{ x: { y: [z] }}` -> `Map{ 'z' => '.x.y[0]' }`
|
||||||
|
function parseValueDestructure() {
|
||||||
|
const map = new Map<string, string>()
|
||||||
if (value) {
|
if (value) {
|
||||||
rawValue = value && value.content
|
rawValue = value && value.content
|
||||||
if ((isDestructure = !!value.ast)) {
|
if (value.ast) {
|
||||||
walkIdentifiers(
|
walkIdentifiers(
|
||||||
value.ast,
|
value.ast,
|
||||||
(id, _, __, ___, isLocal) => {
|
(id, _, parentStack, ___, isLocal) => {
|
||||||
if (isLocal) idsInValue.add(id.name)
|
if (isLocal) {
|
||||||
|
let path = ''
|
||||||
|
for (let i = 0; i < parentStack.length; i++) {
|
||||||
|
const parent = parentStack[i]
|
||||||
|
const child = parentStack[i + 1] || id
|
||||||
|
if (
|
||||||
|
parent.type === 'ObjectProperty' &&
|
||||||
|
parent.value === child
|
||||||
|
) {
|
||||||
|
if (parent.computed && parent.key.type !== 'StringLiteral') {
|
||||||
|
// TODO need to process this
|
||||||
|
path += `[${value.content.slice(
|
||||||
|
parent.key.start!,
|
||||||
|
parent.key.end!,
|
||||||
|
)}]`
|
||||||
|
} else if (parent.key.type === 'StringLiteral') {
|
||||||
|
path += `[${JSON.stringify(parent.key.value)}]`
|
||||||
|
} else {
|
||||||
|
// non-computed, can only be identifier
|
||||||
|
path += `.${(parent.key as Identifier).name}`
|
||||||
|
}
|
||||||
|
} else if (parent.type === 'ArrayPattern') {
|
||||||
|
const index = parent.elements.indexOf(child as any)
|
||||||
|
path += `[${index}]`
|
||||||
|
}
|
||||||
|
// TODO handle rest spread
|
||||||
|
}
|
||||||
|
map.set(id.name, path)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
idsInValue.add(rawValue)
|
map.set(rawValue, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return idsInValue
|
return map
|
||||||
}
|
|
||||||
|
|
||||||
function genBlockFn() {
|
|
||||||
const [depth, exitScope] = context.enterScope()
|
|
||||||
let propsName: string
|
|
||||||
const idMap: Record<string, string | null> = {}
|
|
||||||
if (context.options.prefixIdentifiers) {
|
|
||||||
propsName = `_ctx${depth}`
|
|
||||||
let suffix = isDestructure ? '' : '.value'
|
|
||||||
Array.from(idsInValue).forEach(
|
|
||||||
(id, idIndex) => (idMap[id] = `${propsName}[${idIndex}]${suffix}`),
|
|
||||||
)
|
|
||||||
if (rawKey) idMap[rawKey] = `${propsName}[${idsInValue.size}]${suffix}`
|
|
||||||
if (rawIndex)
|
|
||||||
idMap[rawIndex] = `${propsName}[${idsInValue.size + 1}]${suffix}`
|
|
||||||
} else {
|
|
||||||
propsName = `[${[rawValue || ((rawKey || rawIndex) && '_'), rawKey || (rawIndex && '__'), rawIndex].filter(Boolean).join(', ')}]`
|
|
||||||
}
|
|
||||||
|
|
||||||
const blockFn = context.withId(
|
|
||||||
() => genBlock(render, context, [propsName]),
|
|
||||||
idMap,
|
|
||||||
)
|
|
||||||
exitScope()
|
|
||||||
return blockFn
|
|
||||||
}
|
|
||||||
|
|
||||||
function genSimpleIdMap() {
|
|
||||||
const idMap: Record<string, null> = {}
|
|
||||||
if (rawKey) idMap[rawKey] = null
|
|
||||||
if (rawIndex) idMap[rawIndex] = null
|
|
||||||
idsInValue.forEach(id => (idMap[id] = null))
|
|
||||||
return idMap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this should be looked at for destructure cases
|
||||||
function genCallback(expr: SimpleExpressionNode | undefined) {
|
function genCallback(expr: SimpleExpressionNode | undefined) {
|
||||||
if (!expr) return false
|
if (!expr) return false
|
||||||
const res = context.withId(() => genExpression(expr, context), simpleIdMap)
|
const res = context.withId(
|
||||||
|
() => genExpression(expr, context),
|
||||||
|
genSimpleIdMap(),
|
||||||
|
)
|
||||||
return [
|
return [
|
||||||
...genMulti(
|
...genMulti(
|
||||||
['(', ')', ', '],
|
['(', ')', ', '],
|
||||||
|
@ -135,4 +119,12 @@ export function genFor(
|
||||||
')',
|
')',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genSimpleIdMap() {
|
||||||
|
const idMap: Record<string, null> = {}
|
||||||
|
if (rawKey) idMap[rawKey] = null
|
||||||
|
if (rawIndex) idMap[rawIndex] = null
|
||||||
|
idToPathMap.forEach((_, id) => (idMap[id] = null))
|
||||||
|
return idMap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ export interface ForIRNode extends BaseIRNode, IRFor {
|
||||||
keyProp?: SimpleExpressionNode
|
keyProp?: SimpleExpressionNode
|
||||||
render: BlockIRNode
|
render: BlockIRNode
|
||||||
once: boolean
|
once: boolean
|
||||||
container?: number
|
component: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetPropIRNode extends BaseIRNode {
|
export interface SetPropIRNode extends BaseIRNode {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
type ElementNode,
|
type ElementNode,
|
||||||
|
ElementTypes,
|
||||||
ErrorCodes,
|
ErrorCodes,
|
||||||
type SimpleExpressionNode,
|
type SimpleExpressionNode,
|
||||||
createCompilerError,
|
createCompilerError,
|
||||||
|
@ -46,6 +47,7 @@ export function processFor(
|
||||||
|
|
||||||
const keyProp = findProp(node, 'key')
|
const keyProp = findProp(node, 'key')
|
||||||
const keyProperty = keyProp && propToExpression(keyProp)
|
const keyProperty = keyProp && propToExpression(keyProp)
|
||||||
|
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||||
context.node = node = wrapTemplate(node, ['for'])
|
context.node = node = wrapTemplate(node, ['for'])
|
||||||
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
|
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
|
||||||
const id = context.reference()
|
const id = context.reference()
|
||||||
|
@ -55,15 +57,6 @@ export function processFor(
|
||||||
|
|
||||||
return (): void => {
|
return (): void => {
|
||||||
exitBlock()
|
exitBlock()
|
||||||
const { parent } = context
|
|
||||||
let container: number | undefined
|
|
||||||
if (
|
|
||||||
parent &&
|
|
||||||
parent.block.node !== parent.node &&
|
|
||||||
parent.node.children.length === 1
|
|
||||||
) {
|
|
||||||
container = parent.reference()
|
|
||||||
}
|
|
||||||
context.registerOperation({
|
context.registerOperation({
|
||||||
type: IRNodeTypes.FOR,
|
type: IRNodeTypes.FOR,
|
||||||
id,
|
id,
|
||||||
|
@ -74,7 +67,7 @@ export function processFor(
|
||||||
keyProp: keyProperty,
|
keyProp: keyProperty,
|
||||||
render,
|
render,
|
||||||
once: context.inVOnce,
|
once: context.inVOnce,
|
||||||
container,
|
component: isComponent,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue