浅谈一种让小程序支持JSX语法的新思路(2)

<template> <Text>Hello</Text> </template> <template> <View uuid="000002"> <Image/> <Text/> </View> </template> <!--占位template--> <template is="{{uiDes.name}}" data="{{...uiDes}}"/>

注意这里每一个template 的name标识和 JSX片段的唯一标识uuid是一样的。最后,需要在结尾生成一个占位模版:<template is="{{uiDes.name}}" data="{{...uiDes}}"/>。

第四步:修改ReactDOM.render的递归(React 16.x之后,不在是递归的方式)过程,递归执行阶段,聚合JSX片段的uuid属性,生成并返回uiDes数据结构。

第五步:把第四步生成的uiDes,传递给小程序环境,小程序把uiDes 设置给占位模版<template is="{{uiDes.name}}" data="{{...uiDes}}"/>,渲染出最终的视图。

我们以上面的App组件的例子来说明整个过程,首先js代码会被转义为:

class App extends React.Component { render () { const a = React.createElement(Text, {uuid: "000001"}, "Hello"); const b = a return ( React.createElement(View, {uuid: "000002"} , b); ) } }

同时生成wxml文件:

<template> <Text>Hello</Text> </template> <template> <View> <template is="{{child0001.name}}" data="{{...child0001}}"/> </View> </template> <!--占位template--> <template is="{{uiDes.name}}" data="{{...uiDes}}"/>

使用我们定制之后render执行ReactDOM.render(<App/>, parent)。在render的递归过程中,除了会执行常规的创建组件实例,执行生命周期之外,还会额外的收集执行过程中组件的uuid标识,最终生成 uiDes 对象

const uiDes = { name: "000002", child0001: { name: 000001, ... } ... }

小程序获取到这个uiDes,设置给占位模版<template is="{{uiDes.name}}" data="{{...uiDes}}"/>。 最终渲染出小程序视图。

浅谈一种让小程序支持JSX语法的新思路

在这整个过程中,你的所有JS代码都是运行在React过程中的,语义完全一致,JSX片段也不会被任何特殊处理,只是简单的React.createElement调用,另外由于这里的React过程只是纯js运算,执行是非常迅速的,通常只有几ms。最终会输出一个uiDes数据到小程序,小程序通过这个uiDes渲染出视图。

现在我们在看之前的赋值const b = a,就不会有任何问题了,因为a 不过是普通对象。另外对于常见的编译时方案的限制,比如任意函数返回JSX片段,动态生成JSX片段,for循环使用JSX片段等等,都可以完全解除了,因为JSX片段只是js对象,你可以做任何操作,最终ReactDOM.render会搜集所有执行结果的片段的uuid标识,生成uiDes,而小程序会根据这个uiDes数据结构渲染出最终视图。

可以看出这种新的思路和以前编译时方案还是有很大的区别的,对JSX片段的处理是动态的,你可以在任何地方,任何函数出现任何JSX片段, 最终执行结果会确定渲染哪一个片段,只有执行结果的片段的uuid会被写入uiDes。这和编译时方案的静态识别有着本质的区别。

结语

"Talk is cheap. Show me your code!" 这仅仅是一个思路?还是已经有落地完整的实现呢?

是有完整的实现的,alita项目在处理JSX语法的时候,采用的就是这个思路,这也是alita基本不限制写法却可以转化整个React Native项目的原因,另外alita在这个思路上做了很多优化。如果对这个思路的具体实现有兴趣,可以去研读一下alita源码,它完全是开源的https://github.com/areslabs/alita

当然,你也可以基于这个思路,构造出自己的React小程序开发方案。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f4246047fb352514905c99d990193401.html