areslabs/alita

原理的疑惑

Opened this issue · 9 comments

https://areslabs.github.io/alita/%E4%B8%80%E7%A7%8D%E8%AE%A9%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%94%AF%E6%8C%81JSX%E8%AF%AD%E6%B3%95%E7%9A%84%E6%96%B0%E6%80%9D%E8%B7%AF.html

官网这篇文章中有介绍原理,但是其中有一处有疑惑。
image
预编译时期是怎么知道000002的View里面包含的是个template的,即b的值?

@army8735 这个地方的表述不准确。 准确的过程是这样的(我稍后会更新这个文档)
这里的b 在运行期可能是字符串常量,可能是JSX片段,也可能是JSX片段数组, 所以,准确的wxml如下:

<template name="childTemp">
   <block wx:if="d 是字符串">{{d}}</block>
   <template wx:elif="{{d.name}}" is="{{d.name}}" data="{{...d}}"/>
   <block wx:else>
       <block wx:for="{{d}}" wx:key="key">
           <template is="{{item.name}}" data="{{...item}}"/>
       </block>
   </block>
</template>

<template name="000002">
    <View>
        <template is="childTemp" data="{{d: child0001}}"/>
    </View>
</template>

每一个 wxml文件上面 都会存在一个 name 为childTemp的template。 这个template会值对不同的情况,分别处理。

所以对应JSX children的每一个“变量值”(可能是类似上面的b, 可能是方法调用。。。等等)。 都会先用childTemp占位, 然后具体childTemp渲染的结构,由运行期这个“变量值”的运行结果确定。上面的这个b,可能在这次渲染的时候是个字符串,也可能下一次渲染就是JSX了。

如果b不是jsx数组是个普通数组呢?

在 childTemp 加了一行 😃😃😃

<template name="childTemp">
   <block wx:if="d 是字符串">{{d}}</block>
   <template wx:elif="{{d.name}}" is="{{d.name}}" data="{{...d}}"/>
   <block wx:else>
       <block wx:for="{{d}}" wx:key="key">
            <block wx:if="item 是字符串">{{item }}</block>      // <------ :smiley: 这里加了1行
           <template wx:else is="{{item.name}}" data="{{...item}}"/>
       </block>
   </block>
</template>

还有个疑惑,template里child0001、child0002是按深度遍历顺序出现?

class App extends React.Component {
  render () {
    const a = <Text>a</Text>;
    const b = <Text>b</Text>;
    return (
      <View>
        {b}
        <View>{a}</View>
        123
      </View>
    );
  }
}

export default App;

这样template和js中uiDes对象会是如何?

本身render的收集是递归程序。所以是深度遍历的。

我大概贴一下真实的转化结果
wxml部分:

<template name="childTemp">
   <block wx:if="{{t.l(d)}}">{{d}}</block>
   <template wx:elif="{{d.tempName}}" is="{{d.tempName}}" data="{{...d}}"/>
   <block wx:else>
       <block wx:for="{{d}}" wx:key="key">
           <block wx:if="{{t.l(item)}}">{{item}}</block>
           <template wx:else is="{{item.tempName}}" data="{{...item}}"/>
       </block>
   </block>
</template>

 <template name="ITNP00002">
    <view class="text">a</view>
  </template>
 
 <template name="ITNP00004">
    <view class="text">b</view>
  </template>
 
 <template name="ITNP00007">
    <view class="view">
                <template wx:if="{{CTDK00002}} !== undefined" is="childTemp" data="{{d: CTDK00002}}"></template>
                <view class="view" >
                    <template wx:if="{{CTDK00001}} !== undefined" is="childTemp" data="{{d: CTDK00001}}"></template>
                </view>
                123
            </view>
  </template>

<template wx:if="{{(_r && _r.tempName)}}" is="{{_r.tempName}}" data="{{..._r}}"/>

uiDes 大概是

var uiDes = {
       "tempName":"ITNP00007",
       "CTDK00002":{"tempName":"ITNP00004"},
       "CTDK00001":{"tempName":"ITNP00002"}
}

看到一个更进一步的思路,不需要自己做uiDes的逻辑,直接利用react自己最终render返回的虚拟dom,然后用template递归遍历dom和dom的children渲染

能具体说一下这个思路么 @army8735

不知道template这样递归渲染,粒度这么细的话,不知道会不会有性能方面的问题。:smiley::smiley::smiley: