refactor: merge createTextNode & setText

This commit is contained in:
三咲智子 Kevin Deng 2024-04-20 21:48:44 +08:00
parent b9b3e021de
commit e67e6432f0
No known key found for this signature in database
8 changed files with 41 additions and 36 deletions

View File

@ -120,7 +120,7 @@ export function render(_ctx) {
`;
exports[`compile > directives > v-pre > should not affect siblings after it 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setText as _setText, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp, template as _template } from 'vue/vapor';
const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
const t1 = _template("<div></div>")
@ -129,20 +129,18 @@ export function render(_ctx) {
const n0 = t0()
const n3 = t1()
const n1 = _createComponent(_component_Comp)
const n2 = _createTextNode()
const n2 = _createTextNode(() => [_ctx.bar])
_insert([n1, n2], n3)
_renderEffect(() => _setText(n2, _ctx.bar))
_renderEffect(() => _setDynamicProp(n3, "id", _ctx.foo))
return [n0, n3]
}"
`;
exports[`compile > dynamic root 1`] = `
"import { createTextNode as _createTextNode, setText as _setText } from 'vue/vapor';
"import { createTextNode as _createTextNode } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createTextNode()
_setText(n0, 1, 2)
const n0 = _createTextNode([1, 2])
return n0
}"
`;
@ -163,8 +161,7 @@ export function render(_ctx) {
exports[`compile > expression parsing > interpolation 1`] = `
"(() => {
const n0 = _createTextNode()
_renderEffect(() => _setText(n0, a + b.value))
const n0 = _createTextNode(() => [a + b.value])
return n0
})()"
`;
@ -192,11 +189,10 @@ export function render(_ctx) {
`;
exports[`compile > static + dynamic root 1`] = `
"import { createTextNode as _createTextNode, setText as _setText } from 'vue/vapor';
"import { createTextNode as _createTextNode } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createTextNode()
_setText(n0, 1, 2, "3", 4, 5, "6", 7, 8, "9", 'A', 'B')
const n0 = _createTextNode([1, 2, "3", 4, 5, "6", 7, 8, "9", 'A', 'B'])
return n0
}"
`;

View File

@ -10,8 +10,7 @@ export function render(_ctx) {
const n3 = _next(n0, 2)
const n2 = n3.nextSibling
_setText(n0, 'first')
const n1 = _createTextNode()
_setText(n1, 'second', " ", 'third', " ")
const n1 = _createTextNode(['second', " ", 'third', " "])
_setText(n2, 'forth')
_insert(n1, n4, n3)
return n4

View File

@ -12,14 +12,13 @@ export function render(_ctx) {
`;
exports[`compiler: v-once > basic 1`] = `
"import { createTextNode as _createTextNode, setText as _setText, setClass as _setClass, prepend as _prepend, template as _template } from 'vue/vapor';
"import { createTextNode as _createTextNode, setClass as _setClass, prepend as _prepend, template as _template } from 'vue/vapor';
const t0 = _template("<div><span></span></div>")
export function render(_ctx) {
const n2 = t0()
const n1 = n2.firstChild
const n0 = _createTextNode()
_setText(n0, _ctx.msg, " ")
const n0 = _createTextNode([_ctx.msg, " "])
_setClass(n1, _ctx.clz)
_prepend(n2, n0)
return n2

View File

@ -31,10 +31,6 @@ describe('compiler: v-once', () => {
{
type: IRNodeTypes.CREATE_TEXT_NODE,
id: 0,
},
{
element: 0,
type: IRNodeTypes.SET_TEXT,
values: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
@ -47,6 +43,7 @@ describe('compiler: v-once', () => {
isStatic: true,
},
],
effect: false,
},
{
element: 1,

View File

@ -1,19 +1,19 @@
import type { CodegenContext } from '../generate'
import type { CreateTextNodeIRNode, SetTextIRNode } from '../ir'
import { genExpression } from './expression'
import { type CodeFragment, NEWLINE, genCall } from './utils'
import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils'
export function genSetText(
oper: SetTextIRNode,
context: CodegenContext,
): CodeFragment[] {
const { vaporHelper } = context
const { values } = oper
const { element, values } = oper
return [
NEWLINE,
...genCall(
vaporHelper('setText'),
`n${oper.element}`,
`n${element}`,
...values.map(value => genExpression(value, context)),
),
]
@ -24,9 +24,16 @@ export function genCreateTextNode(
context: CodegenContext,
): CodeFragment[] {
const { vaporHelper } = context
const { id, values, effect } = oper
return [
NEWLINE,
`const n${oper.id} = `,
...genCall(vaporHelper('createTextNode')),
`const n${id} = `,
...genCall(vaporHelper('createTextNode'), [
effect && '() => ',
...genMulti(
['[', ']', ', '],
...values.map(value => genExpression(value, context)),
),
]),
]
}

View File

@ -159,6 +159,8 @@ export interface SetModelValueIRNode extends BaseIRNode {
export interface CreateTextNodeIRNode extends BaseIRNode {
type: IRNodeTypes.CREATE_TEXT_NODE
id: number
values: SimpleExpressionNode[]
effect: boolean
}
export interface InsertNodeIRNode extends BaseIRNode {

View File

@ -11,6 +11,7 @@ import {
} from '@vue/compiler-dom'
import type { NodeTransform, TransformContext } from '../transform'
import { DynamicFlag, IRNodeTypes } from '../ir'
import { isConstantExpression } from '../utils'
type TextLike = TextNode | InterpolationNode
const seen = new WeakMap<
@ -50,17 +51,13 @@ function processTextLike(context: TransformContext<InterpolationNode>) {
const values = nodes.map(node => createTextLikeExpression(node, context))
context.dynamic.flags |= DynamicFlag.INSERT | DynamicFlag.NON_TEMPLATE
context.registerOperation({
type: IRNodeTypes.CREATE_TEXT_NODE,
id,
values,
effect: !values.some(isConstantExpression),
})
context.registerEffect(values, [
{
type: IRNodeTypes.SET_TEXT,
element: id,
values,
},
])
}
function processTextLikeContainer(

View File

@ -1,6 +1,8 @@
import { isArray, toDisplayString } from '@vue/shared'
import { isArray } from '@vue/shared'
import type { Block } from '../apiRender'
import { componentKey } from '../component'
import { renderEffect } from '../renderEffect'
import { setText } from './prop'
/*! #__NO_SIDE_EFFECTS__ */
export function normalizeBlock(block: Block): Node[] {
@ -34,10 +36,16 @@ export function remove(block: Block, parent: ParentNode) {
normalizeBlock(block).forEach(node => parent.removeChild(node))
}
/*! #__NO_SIDE_EFFECTS__ */
export function createTextNode(val?: unknown): Text {
export function createTextNode(values?: any[] | (() => any[])): Text {
// eslint-disable-next-line no-restricted-globals
return document.createTextNode(val === undefined ? '' : toDisplayString(val))
const node = document.createTextNode('')
if (values)
if (isArray(values)) {
setText(node, ...values)
} else {
renderEffect(() => setText(node, ...values()))
}
return node
}
/*! #__NO_SIDE_EFFECTS__ */