Skip to content

Commit be8bc48

Browse files
committed
feat(alita): 简化Text类型标签的处理
1 parent c80ca16 commit be8bc48

File tree

6 files changed

+74
-33
lines changed

6 files changed

+74
-33
lines changed

docs/组件差异-Text.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
## Text
22

33
* numberOfLines 最好和 height 配合使用,否则可能会出现文字显示不全。
4-
4+
5+
* Text 标签的子元素,如果是变量,那么这个变量需要为 简单类型
6+
7+
合法
8+
9+
```javascript
10+
11+
x = 1
12+
13+
<Text>
14+
<Text>{x}</Text>
15+
</Text>
16+
```
17+
18+
非法
19+
20+
```javascript
21+
22+
x = <Text>1</Text>
23+
24+
<Text>
25+
{1}
26+
</Text>
27+
```
28+

packages/wx-react/src/render.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -712,12 +712,25 @@ function updateTemplate(vnode, parentInst, parentContext, data, oldData, dataPat
712712
) {
713713
// do nothing
714714
data[datakey] = ''
715-
} else if (typeof tempVnode === 'string'
715+
return
716+
}
717+
718+
if (typeof tempVnode === 'string'
716719
|| typeof tempVnode === 'number'
717720
) {
718721
// 不是jsx的情况
719722
data[datakey] = tempVnode
720-
} else if (Array.isArray(tempVnode)) {
723+
return
724+
}
725+
726+
if (vnode.props.isTextElement) {
727+
let message = "Text子元素JSX表达式的值只能是简单类型!"
728+
console.error(message)
729+
data[datakey] = ''
730+
return
731+
}
732+
733+
if (Array.isArray(tempVnode)) {
721734
// key必须明确指定,对于不知道key的情况, React和小程序处理可能存在差异,造成两个平台的行为差异
722735

723736
let oldSubDataKeyMap = {}

src/misc/transformJSX.js

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ const transformJSX = (api, options) => {
131131
return attr.type === 'JSXAttribute'
132132
&& (attr.name.name === 'datakey'
133133
|| attr.name.name === 'tempVnode'
134+
|| attr.name.name === 'isTextElement'
134135
)
135136
})
136137
}

src/tran/childrenToTemplate.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import traverse from "@babel/traverse";
1010
import * as t from "@babel/types"
1111

1212
import {geneOrder} from '../util/util'
13-
import {isChildComp} from '../util/uast'
13+
import {isChildComp, isTextElement} from '../util/uast'
1414

1515
import {ChildTemplateDataKeyPrefix, ChildTemplateNamePrefix} from '../constants'
1616

@@ -96,6 +96,7 @@ export default function childrenToTemplate(ast, info) {
9696
traverse(ast, {
9797

9898
exit: path => {
99+
99100
if (path.type === 'JSXElement'
100101
&& !isChildComp(path.node.openingElement.name.name)
101102
) {
@@ -111,16 +112,23 @@ export default function childrenToTemplate(ast, info) {
111112

112113
const datakey = `${ChildTemplateDataKeyPrefix}${goForCTDK.next}`
113114

115+
116+
const templateAttris = [
117+
t.jsxAttribute(t.jsxIdentifier('datakey'), t.stringLiteral(datakey)),
118+
t.jsxAttribute(t.jsxIdentifier('tempVnode'), ele),
119+
t.jsxAttribute(t.jsxIdentifier('wx:if'), t.stringLiteral(`{{${datakey}}} !== undefined`)),
120+
t.jsxAttribute(t.jsxIdentifier('is'), t.stringLiteral(tempName)),
121+
t.jsxAttribute(t.jsxIdentifier('data'), t.stringLiteral(`{{d: ${datakey}}}`))
122+
]
123+
124+
if (isTextElement(path.node.openingElement)) {
125+
templateAttris.push(t.jsxAttribute(t.jsxIdentifier('isTextElement')))
126+
}
127+
114128
return t.jsxElement(
115129
t.jsxOpeningElement(
116130
t.jsxIdentifier('template'),
117-
[
118-
t.jsxAttribute(t.jsxIdentifier('datakey'), t.stringLiteral(datakey)),
119-
t.jsxAttribute(t.jsxIdentifier('tempVnode'), ele),
120-
t.jsxAttribute(t.jsxIdentifier('wx:if'), t.stringLiteral(`{{${datakey}}} !== undefined`)),
121-
t.jsxAttribute(t.jsxIdentifier('is'), t.stringLiteral(tempName)),
122-
t.jsxAttribute(t.jsxIdentifier('data'), t.stringLiteral(`{{d: ${datakey}}}`))
123-
]
131+
templateAttris
124132
),
125133
t.jsxClosingElement(
126134
t.jsxIdentifier('template')

src/tran/literalTemplate.js

+7-22
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import traverse from "@babel/traverse";
1010
import * as t from "@babel/types"
11+
import {isTextElement} from '../util/uast'
1112

1213
/**
1314
* 如果 由childrenToTemplate生成的template 最终运行的结果是literal,那直接展示
@@ -22,34 +23,26 @@ export default function literalTemplate (ast, info) {
2223
if (path.type === 'JSXElement'
2324
&& isTextElement(path.node.openingElement)
2425
) {
25-
const newChildren = []
26-
path.node.children.forEach(item => {
26+
27+
const children = path.node.children
28+
path.node.children = children.map(item => {
2729
if (
2830
item.type === 'JSXElement'
2931
&& item.openingElement.name.name === 'template'
3032
) {
3133

3234
let datakey = null
3335
item.openingElement.attributes.forEach(attr => {
34-
if (attr.type === 'JSXAttribute' && attr.name.name === 'wx:if') {
35-
attr.name.name = 'wx:else'
36-
attr.value = null
37-
}
38-
3936
if (attr.type === 'JSXAttribute' && attr.name.name === 'datakey') {
4037
datakey = attr.value.value
4138
}
4239
})
4340

44-
newChildren.push(
45-
t.jsxText(`<block wx:if="{{t.l(${datakey})}}">{{${datakey}}}</block>`)
46-
)
41+
return t.jsxText(`{{${datakey}}}`)
42+
} else {
43+
return item
4744
}
48-
49-
newChildren.push(item)
5045
})
51-
52-
path.node.children = newChildren
5346
}
5447

5548
}
@@ -59,11 +52,3 @@ export default function literalTemplate (ast, info) {
5952
return ast
6053
}
6154

62-
function isTextElement(openingElement) {
63-
if (openingElement.name.name !== 'view') return false
64-
65-
return openingElement.attributes.some(item =>
66-
item.type === 'JSXAttribute'
67-
&& item.name.name === 'original'
68-
&& (item.value.value === 'OuterText' || item.value.value === 'InnerText'))
69-
}

src/util/uast.js

+10
Original file line numberDiff line numberDiff line change
@@ -292,5 +292,15 @@ export function isBindElementByName(name) {
292292
}
293293

294294

295+
export function isTextElement(openingElement) {
296+
if (openingElement.name.name !== 'view') return false
297+
298+
return openingElement.attributes.some(item =>
299+
item.type === 'JSXAttribute'
300+
&& item.name.name === 'original'
301+
&& (item.value.value === 'OuterText' || item.value.value === 'InnerText'))
302+
}
303+
304+
295305

296306

0 commit comments

Comments
 (0)