// 根据 events 中的 methods 构建事件监听的调用// 并塞入 created 中forEachListenEvents(targetNode: types.ObjectMethod) {this.clzProperty.listenEvents.forEach((item) => {const methodsNode: any = item// 形如 this.$on('test', ()=>{})if (methodsNode?.key?.name) {// 创建 this 表达式const thisEx = t.thisExpression()// 创建 $on 表达式const ide = t.identifier('$eventBus.$on')// 合并 this.$on 表达式const om = t.memberExpression(thisEx, ide)// 创建事件名称参数节点const eventNameIde = t.stringLiteral(methodsNode.key.name.toString().trim())// 获取方法体内代码内容节点const meNode = t.memberExpression(t.thisExpression(),t.identifier(methodsNode.key.name.toString().trim()))const ceNode = t.callExpression(om, [eventNameIde, meNode])const esNode = t.expressionStatement(ceNode)// 将合成后的代码插入到 created 中targetNode.body.body.push(esNode)}}) }3.emitter vue 代码生成
构建完 Vue AST 之后,我们可以调用 generate 函数生成源码字符串:
transform() {const ast = this.buildCompVueAst()const compVue = this.genCode(ast)return { compVue, wxs: this.buildWxs() }}5.4 Wepy page 转换5.4.1 差异性梳理上面的章节已经给大家分析了template、component的代码转换逻辑,这一节主要带大家一起看下如何转换page文件 。page转换的逻辑即如何实现wepy 的 page.wpy 模块转换为 uniapp 的 page.vue 模块 。
首先我们来看下wepy 的 page 小程序实例:
<script>import wepy from 'wepy';import Counter from '../components/counter';export default class Page extends wepy.page {config = {};components = {counter1: Counter};data = https://www.huyubaike.com/biancheng/{};methods = {};events = {};onLoad() {};// Other properties}可以看到,wepy的page类也是通过继承来实现的,页面文件 page.wpy 中所声明的页面实例继承自 wepy.page 类,该类的主要属性介绍如下:
文章插图
5.4.2 核心转换设计基于page的api特性以及实现方案,具体的转换设计思路如下:
文章插图
5.4.3 痛点难点1.非阻塞异步与异步
在进行批量pages转换时,需要同时对pages.json进行读取、修改、再修改的操作,这就涉及到使用阻塞 IO/ 异步 IO来处理文件的读写,当使用异步IO时,会发起多个进程同时处理pages.json, 每个读取完成后单独处理对应的内容,数据不是串行修改,最终导致最终修改的内容不符合预期,因此在遇到并行处配置文件时,需要使用阻塞式io来读取文件,保障最终数据的唯一性,具体代码如下:
// merge pageConfig to app configconst rawPagesJson = fs.readFileSync(path.join(dest, 'src/pages.json'))// 数据操作fs.writeFileSync(path.join(dest, 'src', 'pages.json'),prettJson(pagesJson))2.复杂的事件机制
在转换过程中,我们也碰到一个比较大的痛点:page.wepy 继承至 wepy.page,wepy.page 代码较复杂,需要将明确部分单独抽离出来 。例如说 events 中组件间数据传递:$broadcast
、$emit
、$invoke
,$broadcast
、$invoke
需要熟悉其使用场景,转换为 Vue 中公共方法 。
5.5 Wepy WXML 转换template转换章节中提到了wepy模板中可以直接引入wxml文件,但是uni-app使用的Vue模板不支持直接引入wxml,故我们需要将wxml文件处理为uniapp可以引入的Vue文件 。我们先来看一下wepy中引入的wxml文件的大致结构 。
<template name="foo"><view class="foo-content"><text class="text1">{{item.text1}}</text><image class="pic" src="https://www.huyubaike.com/biancheng/{{pic.url}}" mode="aspectFill"></image></view></template><template name="bar"><view class="bar-content"><image class="bar" src="https://www.huyubaike.com/biancheng/{{pic.url}}" mode="aspectFill"></image><text class="text2">{{item.text2}}</text></view></template><view class="footer">this is footer</view><!-- index.wepy --><!-- 引入文件 --><import src="https://www.huyubaike.com/biancheng/somePath/fooBar.wxml" /><!-- 确定展示的template及传入属性 --><script is="foo" data="https://www.huyubaike.com/biancheng/{{item, pic}}" /><!-- or, 此时仅会展示<template/>以外的内容即footer --><include src="https://www.huyubaike.com/biancheng/somePath/fooBar.wxml">
经验总结扩展阅读
- 做酸奶的菌粉在哪里可以买到
- 惊艳到别人的句子 形容一眼就被吸引的句子
- 贝壳中介费2.5可以优惠么 贝壳中介费到底能不能便宜
- 花甲可以泡到第二天做吗
- 之六 2流高手速成记:从SpringBoot到SpringCloudAlibaba
- 贝壳的中介费最低可以谈到多少 贝壳中介费是买方付还是卖方付
- 格瓦斯到底算不算酒驾
- 便血到底是痔疮还是肠癌 便血是由什么引起的
- 2023年9月22日入学好不好 2023年9月22日入学行吗
- 2023年9月22日举行成年礼行吗 2023年9月22日适合举行成年礼吗