mirror of https://github.com/vuejs/core.git
refactor(compiler-vapor): inline literal value into template
This commit is contained in:
parent
107569b922
commit
00c6e6dc73
|
@ -1,7 +1,7 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`compiler: children transform > children & sibling references 1`] = `
|
||||
"import { next as _next, setText as _setText, createTextNode as _createTextNode, insert as _insert, template as _template } from 'vue/vapor';
|
||||
"import { next as _next, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div><p></p> <!><p></p></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
|
@ -9,10 +9,10 @@ export function render(_ctx) {
|
|||
const n0 = n4.firstChild
|
||||
const n3 = _next(n0, 2)
|
||||
const n2 = n3.nextSibling
|
||||
_setText(n0, 'first')
|
||||
const n1 = _createTextNode(['second', " ", 'third', " "])
|
||||
_setText(n2, 'forth')
|
||||
const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "])
|
||||
_insert(n1, n4, n3)
|
||||
_renderEffect(() => _setText(n0, _ctx.first))
|
||||
_renderEffect(() => _setText(n2, _ctx.forth))
|
||||
return n4
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -23,12 +23,11 @@ export function render(_ctx) {
|
|||
`;
|
||||
|
||||
exports[`v-text > should raise error if has no expression 1`] = `
|
||||
"import { setText as _setText, template as _template } from 'vue/vapor';
|
||||
"import { template as _template } from 'vue/vapor';
|
||||
const t0 = _template("<div></div>")
|
||||
|
||||
export function render(_ctx) {
|
||||
const n0 = t0()
|
||||
_setText(n0, "")
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
|
|
@ -21,10 +21,10 @@ describe('compiler: children transform', () => {
|
|||
test('children & sibling references', () => {
|
||||
const { code, vaporHelpers } = compileWithElementTransform(
|
||||
`<div>
|
||||
<p>{{'first'}}</p>
|
||||
{{'second'}}
|
||||
{{'third'}}
|
||||
<p>{{'forth'}}</p>
|
||||
<p>{{ first }}</p>
|
||||
{{ second }}
|
||||
{{ third }}
|
||||
<p>{{ forth }}</p>
|
||||
</div>`,
|
||||
)
|
||||
expect(code).toMatchSnapshot()
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from '@vue/compiler-dom'
|
||||
import type { NodeTransform, TransformContext } from '../transform'
|
||||
import { DynamicFlag, IRNodeTypes } from '../ir'
|
||||
import { isConstantExpression } from '../utils'
|
||||
import { getLiteralExpressionValue, isConstantExpression } from '../utils'
|
||||
|
||||
type TextLike = TextNode | InterpolationNode
|
||||
const seen = new WeakMap<
|
||||
|
@ -65,11 +65,16 @@ function processTextLikeContainer(
|
|||
context: TransformContext<ElementNode>,
|
||||
) {
|
||||
const values = children.map(child => createTextLikeExpression(child, context))
|
||||
context.registerEffect(values, {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
element: context.reference(),
|
||||
values,
|
||||
})
|
||||
const literals = values.map(getLiteralExpressionValue)
|
||||
if (literals.every(l => l != null)) {
|
||||
context.childrenTemplate = literals.map(l => String(l))
|
||||
} else {
|
||||
context.registerEffect(values, {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
element: context.reference(),
|
||||
values,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function createTextLikeExpression(node: TextLike, context: TransformContext) {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
|
|||
import { IRNodeTypes } from '../ir'
|
||||
import { EMPTY_EXPRESSION } from './utils'
|
||||
import type { DirectiveTransform } from '../transform'
|
||||
import { getLiteralExpressionValue } from '../utils'
|
||||
|
||||
export const transformVText: DirectiveTransform = (dir, node, context) => {
|
||||
let { exp, loc } = dir
|
||||
|
@ -18,9 +19,14 @@ export const transformVText: DirectiveTransform = (dir, node, context) => {
|
|||
context.childrenTemplate.length = 0
|
||||
}
|
||||
|
||||
context.registerEffect([exp], {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
element: context.reference(),
|
||||
values: [exp],
|
||||
})
|
||||
const literal = getLiteralExpressionValue(exp)
|
||||
if (literal != null) {
|
||||
context.childrenTemplate = [String(literal)]
|
||||
} else {
|
||||
context.registerEffect([exp], {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
element: context.reference(),
|
||||
values: [exp],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { NumericLiteral, StringLiteral } from '@babel/types'
|
||||
import type { BigIntLiteral, NumericLiteral, StringLiteral } from '@babel/types'
|
||||
import { isGloballyAllowed } from '@vue/shared'
|
||||
import {
|
||||
type AttributeNode,
|
||||
|
@ -55,13 +55,20 @@ export function resolveExpression(exp: SimpleExpressionNode) {
|
|||
|
||||
export function getLiteralExpressionValue(
|
||||
exp: SimpleExpressionNode,
|
||||
): number | string | null {
|
||||
if (
|
||||
!__BROWSER__ &&
|
||||
exp.ast &&
|
||||
['StringLiteral', 'NumericLiteral'].includes(exp.ast.type)
|
||||
) {
|
||||
return (exp.ast as StringLiteral | NumericLiteral).value
|
||||
): number | string | boolean | null {
|
||||
if (!__BROWSER__ && exp.ast) {
|
||||
if (
|
||||
['StringLiteral', 'NumericLiteral', 'BigIntLiteral'].includes(
|
||||
exp.ast.type,
|
||||
)
|
||||
) {
|
||||
return (exp.ast as StringLiteral | NumericLiteral | BigIntLiteral).value
|
||||
} else if (
|
||||
exp.ast.type === 'TemplateLiteral' &&
|
||||
exp.ast.expressions.length === 0
|
||||
) {
|
||||
return exp.ast.quasis[0].value.cooked!
|
||||
}
|
||||
}
|
||||
return exp.isStatic ? exp.content : null
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue