Skip to content

Commit e1445ae

Browse files
committed
feat(compiler): support v-text directive
1 parent 18b77fc commit e1445ae

File tree

6 files changed

+185
-8
lines changed

6 files changed

+185
-8
lines changed

packages/compiler/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ export { transformVHtml } from './transforms/vHtml'
2424
export { transformVFor } from './transforms/vFor'
2525
export { transformVIf } from './transforms/vIf'
2626
export { transformVOnce } from './transforms/vOnce'
27+
export { transformVText } from './transforms/vText'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { transformVText as _transformVText } from '@vue/compiler-vapor'
2+
import { resolveDirectiveNode, resolveNode } from '../utils'
3+
import type { DirectiveTransform } from '../transform'
4+
5+
export const transformVText: DirectiveTransform = (dir, node, context) => {
6+
return _transformVText(
7+
resolveDirectiveNode(dir, context),
8+
resolveNode(node, context),
9+
context as any,
10+
)
11+
}

packages/compiler/test/transforms/__snapshots__/vIf.spec.ts.snap

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
exports[`compiler: v-if > comment between branches 1`] = `
44
"
5+
const n17 = t3()
56
const n1 = _createIf(() => ("ok"), () => {
67
const n3 = t0()
78
return n3
@@ -12,7 +13,7 @@ exports[`compiler: v-if > comment between branches 1`] = `
1213
const n14 = t2()
1314
return n14
1415
}), true)
15-
return n1
16+
return [n1, n17]
1617
"
1718
`;
1819

@@ -36,7 +37,8 @@ exports[`compiler: v-if > template v-if 1`] = `
3637
const n2 = t0()
3738
const n3 = t1()
3839
const n4 = t2()
39-
_setText(n4, () => (msg))
40+
const x4 = _child(n4)
41+
_renderEffect(() => _setText(x4, _toDisplayString(msg)))
4042
return [n2, n3, n4]
4143
})
4244
return n0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`v-text > should convert v-text to setText 1`] = `
4+
"
5+
const n0 = t0()
6+
const x0 = _child(n0)
7+
_renderEffect(() => _setText(x0, _toDisplayString(str.value)))
8+
return n0
9+
"
10+
`;
11+
12+
exports[`v-text > should raise error and ignore children when v-text is present 1`] = `
13+
"
14+
const n0 = t0()
15+
const x0 = _child(n0)
16+
_renderEffect(() => _setText(x0, _toDisplayString(test)))
17+
return n0
18+
"
19+
`;
20+
21+
exports[`v-text > should raise error if has no expression 1`] = `
22+
"
23+
const n0 = t0()
24+
return n0
25+
"
26+
`;

packages/compiler/test/transforms/vIf.spec.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
transformElement,
99
transformText,
1010
transformVIf,
11-
// transformVText,
11+
transformVText,
1212
} from '../../src'
1313
import { makeCompile } from './_utils'
1414

@@ -21,7 +21,7 @@ const compileWithVIf = makeCompile({
2121
transformChildren,
2222
],
2323
directiveTransforms: {
24-
// text: transformVText,
24+
text: transformVText,
2525
},
2626
})
2727

@@ -69,12 +69,28 @@ describe('compiler: v-if', () => {
6969

7070
test('template v-if', () => {
7171
const { code, ir } = compileWithVIf(
72-
`<template v-if={ok}><div/>hello<p>{msg}</p></template>`,
72+
`<template v-if={ok}><div/>hello<p v-text={msg}></p></template>`,
7373
)
7474
expect(code).matchSnapshot()
7575

76-
expect(ir.template).toEqual(['<div></div>', 'hello', '<p></p>'])
77-
expect(ir.block.effect).toEqual([])
76+
expect(ir.template).toEqual(['<div></div>', 'hello', '<p> </p>'])
77+
expect((ir.block.operation[0] as IfIRNode).positive.effect).toMatchObject([
78+
{
79+
operations: [
80+
{
81+
type: IRNodeTypes.SET_TEXT,
82+
element: 4,
83+
values: [
84+
{
85+
content: 'msg',
86+
type: NodeTypes.SIMPLE_EXPRESSION,
87+
isStatic: false,
88+
},
89+
],
90+
},
91+
],
92+
},
93+
])
7894
expect((ir.block.operation[0] as IfIRNode).positive.dynamic).toMatchObject({
7995
id: 1,
8096
children: {
@@ -218,11 +234,17 @@ describe('compiler: v-if', () => {
218234
<p v-else-if="orNot"/>
219235
{/* bar */}
220236
<template v-else>fine</template>
237+
<div v-text="text" />
221238
</>
222239
`,
223240
)
224241
expect(code).toMatchSnapshot()
225-
expect(ir.template).toEqual(['<div></div>', '<p></p>', 'fine'])
242+
expect(ir.template).toEqual([
243+
'<div></div>',
244+
'<p></p>',
245+
'fine',
246+
'<div>text</div>',
247+
])
226248
})
227249

228250
describe.todo('errors')
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { describe, expect, test, vi } from 'vitest'
2+
import { BindingTypes, DOMErrorCodes, NodeTypes } from '@vue/compiler-dom'
3+
import {
4+
IRNodeTypes,
5+
transformChildren,
6+
transformElement,
7+
transformVText,
8+
} from '../../src'
9+
import { makeCompile } from './_utils'
10+
11+
const compileWithVText = makeCompile({
12+
nodeTransforms: [transformElement, transformChildren],
13+
directiveTransforms: {
14+
text: transformVText,
15+
},
16+
})
17+
18+
describe('v-text', () => {
19+
test('should convert v-text to setText', () => {
20+
const { code, ir, helpers } = compileWithVText(`<div v-text={str}></div>`, {
21+
bindingMetadata: {
22+
str: BindingTypes.SETUP_REF,
23+
},
24+
})
25+
26+
expect(helpers).contains('setText')
27+
expect(ir.block.operation).toMatchObject([
28+
{
29+
type: IRNodeTypes.GET_TEXT_CHILD,
30+
parent: 0,
31+
},
32+
])
33+
34+
expect(ir.block.effect).toMatchObject([
35+
{
36+
expressions: [
37+
{
38+
type: NodeTypes.SIMPLE_EXPRESSION,
39+
content: 'str',
40+
isStatic: false,
41+
},
42+
],
43+
operations: [
44+
{
45+
type: IRNodeTypes.SET_TEXT,
46+
element: 0,
47+
values: [
48+
{
49+
type: NodeTypes.SIMPLE_EXPRESSION,
50+
content: 'str',
51+
isStatic: false,
52+
},
53+
],
54+
},
55+
],
56+
},
57+
])
58+
59+
expect(code).matchSnapshot()
60+
})
61+
62+
test('should raise error and ignore children when v-text is present', () => {
63+
const onError = vi.fn()
64+
const { code, ir, preamble } = compileWithVText(
65+
`<div v-text={test}>hello</div>`,
66+
{
67+
onError,
68+
},
69+
)
70+
expect(onError.mock.calls).toMatchObject([
71+
[{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }],
72+
])
73+
74+
// children should have been removed
75+
expect(ir.template).toEqual(['<div> </div>'])
76+
77+
expect(ir.block.effect).toMatchObject([
78+
{
79+
expressions: [
80+
{
81+
type: NodeTypes.SIMPLE_EXPRESSION,
82+
content: 'test',
83+
isStatic: false,
84+
},
85+
],
86+
operations: [
87+
{
88+
type: IRNodeTypes.SET_TEXT,
89+
element: 0,
90+
values: [
91+
{
92+
type: NodeTypes.SIMPLE_EXPRESSION,
93+
content: 'test',
94+
isStatic: false,
95+
},
96+
],
97+
},
98+
],
99+
},
100+
])
101+
102+
expect(code).matchSnapshot()
103+
// children should have been removed
104+
expect(preamble).contains('template("<div> </div>", true)')
105+
})
106+
107+
test('should raise error if has no expression', () => {
108+
const onError = vi.fn()
109+
const { code } = compileWithVText(`<div v-text></div>`, { onError })
110+
expect(code).matchSnapshot()
111+
expect(onError.mock.calls).toMatchObject([
112+
[{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }],
113+
])
114+
})
115+
})

0 commit comments

Comments
 (0)