一种让小程序支持JSX语法的新思路_第1页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一种让小程序支持jsx语法的新思路react社区向来在探寻用法react语法开发小程序的方式,其中比较闻名的项目有taro,nanachi。而用法react语法开发小程序的难点主要就是在jsx语法上,jsx本质上是js,相比于小程序静态模版来说太灵便。本文所说的新思路就是在处理jsx语法上的新思路,这是一种越发动态的处理思路,相比于现有计划,基本上不会限制任何jsx的写法,让你以真正的react方式处理小程序,希翼这个新思路可以给任何有志于用react开发小程序的人带来启发。 现有思路的局限 在介绍新的思路之前,我们先来看下taro(最新版1.3),nanachi是怎么在小程序端处理jsx语法

2、的。容易来说,主要是通过在编译阶段把jsx转化为等效的小程序wxml来把react代码运行在小程序端的。 举个例子,比如react规律表达式: xx && hello 将会被转化为等效的小程序wx:if命令: hello 这种方式把对jsx的处理,主要放在了编译阶段,他依靠于编译阶段的信息收集,以上面为例,它必需识别出规律表达式,然后做对应的wx:if转换处理。 那编译阶段有什么问题和局限呢?我们以下面的例子解释: class app extends react.component render () const a = hello const b = a re

3、turn ( b ) 首先我们声明 const a = hello,然后把a赋值给了b,我们看下最新版本taro 1.3的转换,如下图: 这个例子不是特殊复杂,却报错了。 要想理解上面的代码为什么报错,我们首先要理解编译阶段。本质上来说在编译阶段,代码其实就是‘字符串’,而编译阶段处理计划,就需要从这个‘字符串’中分析出须要的信息(通过ast,正则等方式)然后做对应的等效转换处理。 而对于上面的例子,需要做什么等效处理呢?需要我们在编译阶段分析出b是jsx片段:b = a = hello,然后把b中的b等效替换为h

4、ello。然而在编译阶段要想确定b的值是很困难的,有人说可以往前追溯来确定b的值,也不是不行以,但是考虑一下 因为b = a,那么就先要确定a的值,这个a的值怎么确定呢?需要在b可以拜访到的作用域链中确定a,然而a可能又是由其他变量赋值而来,循环往复,期间一旦浮现不是容易赋值的状况,比如函数调用,三元推断等运行时信息,追溯就宣告失败,要是a本身就是挂在全局对象上的变量,追溯就越发无从谈起。 所以在编译阶段 是无法容易确定b的值的。 我们再认真看下上图的报错信息:a is not defined。 为什么说a未定义呢?这是涉及到另外一个问题,我们知道hello,其实等效于react.create

5、element(text, null, &39;hello&39;),而react.createelement办法的返回值就是一个一般js对象,形如 / reactelement对象 tag: text, props: null, children: &39;hello&39; . 所以上面那一段代码在js环境真正运行的时候,也许等效如下: class app extends react.component render () const a = tag: text, props: null, children: &39;hello&39; .

6、const b = a return tag: view, props: null, children: b . 但是,我们刚说了编译阶段需要对jsx做等效处理,需要把jsx转换为wxml,所以hello这个jsx片段被特别处理了,a不再是一个一般js对象,这里我们看到a变量甚至走失了,这里裸露了一个很严峻的问题:代码语义被破坏了,也就是说因为编译时计划对jsx的特别处理,真正运行在小程序上的代码语义并不是你的预期。这个是比较头疼。 新的思路 正由于编译时计划,有如上的限制,在用法的时候经常让你有我还是在写react吗?这种感觉。 下面我们介绍一种全新的处理思路,这种思路在小程序运行期间和真正

7、的react几无区分,不会转变任何代码语义,jsx表达式只会被处理为react.createelement办法调用,实际运行的时候就是一般js对象,终于通过其他方式渲染出小程序视图。下面我们认真解释一下这个思路的详细内容。 第一步:给每个自立的jsx片段打上唯一标识uuid,假定我们有如下代码: const a = hello const y = 我们给a片段,y片段 添加了uuid属性 其次步:把react代码通过babel转义为小程序可以识别的代码,例如jsx片段用等效的react.createelement替换等 const a = react.createelement(text, u

8、uid: "000001" , "hello"); 第三步:提取每个自立的jsx片段,用小程序template小包,生成wxml文件 hello 注重这里每一个template 的name标识和 jsx片段的唯一标识uuid是一样的。最后,需要在结尾生成一个占位模版:。 第四步:修改reactdom.render的递归(react 16.x之后,不在是递归的方式)过程,递归执行阶段,聚合jsx片段的uuid属性,生成并返回uides数据结构。 第五步:把第四步生成的uides,传递给小程序环境,小程序把uides 设置给占

9、位模版,渲染出终于的视图。 我们以上面的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文件: hello 用法我

10、们定制之后render执行reactdom.render(, parent)。在render的递归过程中,除了会执行常规的创建组件实例,执行生命周期之外,还会额外的收集执行过程中组件的uuid标识,终于生成 uides 对象 const uides = name: "000002", child0001: name: 000001, . . 小程序猎取到这个uides,设置给占位模版。 终于渲染出小程序视图。 在这囫囵过程中,你的全部js代码都是运行在react过程中的,语义彻低全都,jsx片段也不会被任何特别处理,只是容易的react.createelem

11、ent调用,另外因为这里的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!&am

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论