megalo -- 网易考拉小程序解决方案

megalo 是基于 Vue 的小程序框架(没错,又是基于 Vue 的小程序框架),但是它不仅仅支持微信小程序,还支持支付宝小程序,同时还支持在开发时使用更多 Vue 的特性。

背景

对于用户而言,小程序能提供更好的体验,但对于开发者而言,要让一个应用跑在多个平台上,则需要写多套代码。如何提高小程序开发效率让很多开发者都感到头疼。

业界也有相关的解决方案,如 taro 和 mpvue,二者都是基于 react 和 vue 的开发模式实现,让开发者能够以他们熟知的 react 或 vue 模式来开发小程序,提高开发效率。

mpvue 的发布给了我们很多启发,更早的时候,我们基于 RegularJS(网易自研的前端框架)开发了一个名为 mpregular 的小程序框架。在 mpregular 的开发和实际使用过程中,我们发现如果小程序框架所支持的特性只是原框架的子集(例如不支持 filter、模版复杂表达式等),开发效率会大打折扣。

所以,我们在方案上做了很多尝试,目的是支持更多的特性,减少小程序与 H5 开发之前的差异。目前 mpregular 已经在考拉的小程序业务中大量应用,相关业务的开发同学纷纷表示,学习成本变低,跨端业务(H5 和小程序)的开发效率提升近一倍。

方案经过一段时间验证后,我们决定把这套方案用 vue 再实现一次,一是为了适应技术栈的变更升级,二是为社区做一点微小的工作,于是就便有了 megalo。

特性

支持更多模版语法特性

相比于其他小程序开发模式,由于支持更多特性,megalo 更贴近 Vue 原生的开发模式。

特性 小程序 mpvue megalo
computed 计算属性 ? ?? ??
v-model 双向绑定 ? ? ??
slot 插槽 ?? ?? ??
scoped-slot 插槽 ? ? ??
filter 过滤器 ? ? ??
v-html 富文本 ? ? ??
复杂表达式插值 ? ? ??

从表格可以看到,megalo 最大的特点之一是,支持更多的 Vue 语法特性。这意味着,如果你有一个需求是要把现有的 Vue 代码迁移到小程序上,不需要太多改动。因为你的代码中可能大量使用 filter、scoped-slot、复杂表达式插值。

基本语法

支持 vue 的基本模版语法,包括 v-forv-if。class 和 style 的绑定方式没有限制,官方的用法都支持。

<!-- v-if & v-for -->
<div v-for="(item, i) in list">
  <div v-if="isEven(i)">{{ i }} - {{ item }}</div>
</div>

<!-- style & class -->
<div :class="classObject"></div>
<div :class="{ active: true }"></div>
<div :class="[activeClass, errorClass]"></div>
<div :style="{ color: activeColor, fontSize: fontSize + ‘px‘ }"></div>
<div :style="styleObject"></div>
<div :style="[baseStyles, overridingStyles]"></div>

slot & scoped-slot

支持 slot 和 scoped-slot。

<div>
  <Container>
    <Card>
      <div slot="head"> {{ title }} </div>
      <div> I‘m body </div>
      <div slot="foot"> I‘m footer </div>
    </Card>
  </Container>
  <List :list="list">
    <span slot-scope="scopeProps">{{ scopeProps.item.label }}</span>
  </List>
<div>

复杂表达式 & filter

可以在模版里面写复杂表达式、调用实例上的方法,当然也可以用更简洁的 filter 语法,跟平时用 Vue 开发一样。

<div>
  <div>{{ message.toUpperCase() }}</div>
  <div>{{ toUpperCase( message ) }</div>
  <div>{{ message | toUpperCase }}</div>
</div>

v-html

要使用 v-html 需要添加插件 @megalo/vhtml-plugin,并引入模版解析库 octoparse,在页面入口安装一下插件:

import Vue from ‘vue‘
import VHtmlPlugin from ‘@megalo/vhtml-plugin‘

Vue.use(VHtmlPlugin)

利用 v-html 指令然后就可以在小程序中渲染 html 了。

<div v-html="‘<h1>megalo</h1>‘"></div>

更好的数据更新性能

小程序的官方明确说明,在调用 setData 更新数据时如果数据量过大或频率更高,会引发性能问题。megalo 在框架底层已经帮开发者对此进行优化,每次数据发生变化时,megalo 只会将视图中要展示的、且发生变化的数据进行更新,将 setData 的数据更新量最小化,同时对更新数据频率进行了限制。

像下面这段代码,如果视图只需要展示 user.name 这个字段的话,在进行数据同步时只会将 user.name 这个字符串更新到视图层,其余字段是不会同步到小程序的对象上的。

<div>{{ user.name }}</div>
<script>
export default {
  data() {
    return {
      user: {
        name: ‘kaola‘,
        age: 3,
        favorite: [
          ‘encalyptus‘,
          ‘sleeping‘
        ]
      }
    }
  }
}
</script>

支持更多平台

今年以来,各大流量平台都在小程序领域有所动作,蚂蚁金服成立小程序事业部,百度、今日头条也纷纷推出自己的小程序。megalo 目前已经支持微信和支付宝小程序,百度小程序等平台的支持也在计划当中。

微信和支付宝小程序

使用

使用 megalo 开发非常简单,只需在常见的 Vue 项目 webpack 构建配置上配置 @megalo/target 并引入 @magalo/template-compiler 即可。如果需要编译成支付宝小程序,只需要设置 platform: ‘alipay‘

const { createMegaloTarget } = require(‘@megalo/target‘);
module.exports = {
  target: createMegaloTarget( {
    compiler: require(‘@megalo/template-compiler‘),
    platform: ‘wechat‘
  } )
  // 其他 webpack 配置,如 vue-loader 等
};

接着,就可以像开发 Vue 应用一样去开发小程序。示例可以参考 megalo-demo

如果想用 typescript 进行开发,可以参考 megalo-ts-simple

实现

小程序在结构上主要有 Service(JavascriptCore) 和 View(WebView) 两部分组成(微信和支付宝小程序有着类似的结构,下文均以微信小程序为例,并简称为小程序),分别运行在独立的环境上,之间不具备共享数据通道,二者的通信方式是将数据封装在 js 脚本后传递。Page 实例就在 Service 中,通过 setData 方法将数据传递到 View。View 则通过事件绑定将视图层触发的事件传递给 Service。Service 层中无法操作视图层的 DOM 节点。

实际开发中,小程序的逻辑和模版需要写在 .js.wxml 两个文件中,分别在 Service 和 View 中执行。如果要将在浏览器端的 Vue 放到小程序中跑,需要将 .vue 文件中的 template 片段转换成 .wxml 文件,并对 Vue 的 runtime 部分改造,将其中的 DOM 操作移除,通过小程序的 Service 中的页面实例上的 API 与 View 进行通信。

最终的运行效果是,当 Vue 的 vm 上数据发生更新时,会重新渲染出 vdom,在的 patch 阶段,框架不在去操作 DOM,而是通过 Page 上的 setData 方法将变化的数据更新到视图层,完成 Vue 和 小程序的视图更新,这就是 megalo 底层所做的工作。

megalo 的实现,主要分成以下四个部分,下面本文将对每个部分进行介绍。

生命周期

小程序中,每一个页面(Page)是一个实例,页面的生命周期钩子有很多,但和实例创建的两个关键生命周期分别是 onLoadonReady,它们分别在「页面加载,实例初始化后」和「初次页面渲染完成」时触发。Vue 的实例要和小程序实例建立起联系,则需要在小程序 Page 实例创建好以后,即在 onLoad 的钩子函数里,去初始化对应的 Vue 根实例,将页面实例 page 挂载到 Vue 实例的 $mp 上,此时也会触发 Vue 的生命周期钩子 created。在页面初次渲染完成后,则会调用 $mount 方法,与在浏览器中挂载 DOM 节点不同,这里会将 Vue 实例上的数据初始化到视图层中。由此,Vue 实例就与小程序的 Page 实建立起了联系。

除了这两个生命周期钩子以外,像小程序的 onShowonHide 等生命周期钩子在触发时,也会尝试触发 Vue 实例上的同名钩子函数,实现两种实例间生命周期的绑定。在小程序页面退出销毁时,会触发 onUnload 钩子,此时 Vue 的实例也会跟着销毁。

模版转换

小程序有它特有的模版语法和文件名后缀,所以在构建阶段,我们会将 .vue 文件中的 template 部分提取出来并转换成对应的 .wxml 文件。标签名、语法都会进行相应的转换,如图所示。

这一部分是在构建阶段完成的,这意味着,megalo 不支持 render 函数的写法。在构建阶段除了将模版转换成 .wxml 以外,还需要对模版中的每个节点进行转换,并在生产的 render 函数中加入相关的节点标记信息,数据映射和事件代理需要这些信息。

数据映射

由于无法直接操作视图层的 DOM,所以我们只能利用 page.setData 这个方法完成数据到视图层的映射。最简单暴力的方法,是将 Vue 实例上的所有数据统统收集起来,通过调用 page.setData 方法更新 Page 实例的数据,这个方法会将数据挂载到 Page 实例上,同时也会把数据传递给视图层。

但是,这种粗暴的更新方式有两个弊端:

i. 全量更新 vm 上的数据是无法区分哪些数据是视图层需要的,冗余无用的数据会被更新到 page 实例上。像下图这个例子,视图层只需要展现两个字符串,如果 vm 上还存在两个大数组,它们也会被无脑同步到 page 上。

ii. 同步到 page 实例上的数据其实就是原始数据,并不是视图层实际要展示的数据,所以展示数据的格式化与转换需要依赖小程序模版的解析能力,导致一些 Vue 支持的模版语法无法支持,例如 filter、复杂表达式、传递 class 对象等。

当然以上两个弊端不会对功能开发造成影响,但在实际的业务开发中,会让开发体验不一致,尤其是 H5 代码迁移到小程序时,对效率影响颇大。为了解决这个问题,megalo 采用另一种方式,即将 render 时生成的 vnode 上的数据更新到视图,vnode 的数据就是已经处理好的展示数据,根据 vnode 构造每个节点的数据结构,再同步到视图层。

例如以下这段代码,在构建阶段 megalo 会对每个节点进行标记,使 render 时生成的 vnode 和模版中每个插值能够对应上。

<!-- 编译前的 Vue 模版 .vue -->
<div :class=“classObj”>
  {{ date | format( ‘YYYY‘ ) }}
</div>

<!-- 编译后的小程序模版 .wxml -->
<view class="{{ node_1.class }}">
  {{ node_2.text }}
</view>

以这种方式实现的数据映射,只有视图层需要的两个字符串数据会被同步到小程序的 Page 实例上,其余数据则被认为与视图无关则不会进行同步。

export default {
  data() {
    return {
      classObj: {
        ‘kaola‘: true
      },
      date: new Date(),
      users: {
        // big object
      }
    }
  }
}

如下图所示,Vue 渲染出来的 vnode 会被以特定的数据结构映射到 page 上,再同步到小程序视图层。

以这种方式实现的数据映射,可以更好地支持 Vue 的模版语法,且更大限度地减少更新视图时传输的数据量,从框架层面规避 setData 的性能问题。

事件代理

小程序视图触发事件后,会将 event 对象通知到 Page 实例,那么我们只需要将视图层中所有的事件都代理到 page.proxy 这个方法中,然后再靠这个方法从 Vue 的实例树上找到对应的 vmhandler 做事件处理。为了实现这一目的,在构建阶段对模版进行编译时,除了要将事件监听方法转换为 proxy 以外,还需要通过 data- 在元素上标记对应的组件 compid 和节点 nodeid

<!-- 编译前的 Vue 模版 .vue -->
<div @click="onClick"></div>

<!-- 编译后的小程序模版 .wxml -->
<view bindtap="proxy" data-compid="0" data-nodeid="0"></view>

事件触发时,proxy 方法会从 event 对象上获取对应的 id 信息和事件类型,进而从 Vue 的根 vm 开始查找,最终在 vnode 上找到对应的 handler 并执行事件处理,完成小程序事件到 Vue 实例的事件代理。

现在与未来

目前,megalo 已经逐步在考拉的小程序应用开发中投入使用,但 megalo 的数据映射方案早已通过 mpregular 在考拉的大量小程序应用中得到了验证。现在,megalo 支持 typescript 开发,支持支付宝小程序。

百度智能小程序的支持也在计划之内,同时,我们还计划开发一个兼容个平台的 UI 组件库、API 库,尝试将跨 H5 和各小程序平台的应用开发之间的差异最小化,提升开发效率。

github

参考

原文地址:https://www.cnblogs.com/elcarim5efil/p/9925431.html

时间: 2024-11-05 22:52:15

megalo -- 网易考拉小程序解决方案的相关文章

网易考拉向欧洲市场投入220亿,能掀起多大波澜?

距离在德国法兰克福举办的欧洲招商会已有半个月的时间了,网易考拉高调宣称将在欧洲市场投入30亿欧元(220亿人民币)的消息在欧洲市场引起了不小的关注,多家欧洲媒体均报道了此事,众多欧洲品牌均有意借着网易考拉的资金投入而尝试进入中国市场. 丁磊坚定要把网易考拉打造成新王牌 对于正处在春风得意之际,游戏赚钱能力堪比腾讯,市值比肩京东的网易而言,3年投入220亿不算什么大事,丁磊已坚定的选择在跨境电商市场打造另一张网易王牌. 在网易公布的2016年度财报以及第四季度财报中显示,网易去年全年净收入381.

一步步教您学会大数据采集之网易考拉海购商品数据采集教程

本文主要介绍如何使用后羿采集器的智能模式,免费采集网易考拉商品的价格.累计评价.商品图片等信息. 采集工具简介: 后羿采集器是一款基于人工智能技术的网络爬虫软件,只需要输入网址就能够自动识别网页数据,无需配置即可完成数据采集,是业内首家支持三种操作系统(包括Windows.Mac和Linux)的采集工具. 该软件是一款真正免费的数据采集软件,对采集结果导出没有任何限制,没有编程基础的小白用户也可轻松实现数据采集要求. 官方网址:http://www.houyicaiji.com/ 采集对象简介:

网易严选、京东、天猫、网易考拉海购、微小店,5种电商类原型模板集合(免费使用)

即将到来的618全民购物狂欢节,你的钱包准备好了吗? 说到网上购物,现在电商APP真的是多种多样,虽说充分满足了人们的需求,但真正能够让大家耳熟能详,愿意重复使用的电商类APP却少之又少.这里我们整理了5款较可靠.超人气的电商APP原型模板,来为你的原型设计增添灵感- 原型模板介绍 网易严选 国内首个ODM(原始设计制造商)模式的电商.网易严选APP首页主要集中展示商品内容,有“首页”.“专题”.“分类”.“购物车”.“个人”五个标签导航,分别承担着不同的功能.其中“首页”页面提供“搜索”.“消

网易考拉等巨头的“电商+直播”模式,或是找到了新的突破口?

跨境电商和移动视频直播都是近期颇为热门的话题.跨境电商摊上热点在于一波三折的税改新政:曾经一度的风口产业在历经4月8日的税改后,导致绝大部分的进口商品无法进入中国,很多跨境电商平台面临无货可卖的尴尬境地;而5月24日海关总署的公告,又让整个行业松了一口气,一年的“缓刑期”不仅给足跨境电商平台思考应对的时间,也预告着未来无限的可能性. 后起之秀移动视频直播受到追捧恰恰是跨境电商行业处于“水深火热”期.或许是直播模式极强的传播互动性,广泛的受众和独特的盈利模式,亦或是跨境电商平台想要破局变革,摆脱税

小程序解决方案 Westore - 组件、纯组件、插件开发

数据流转 先上一张图看清 Westore 怎么解决小程序数据难以管理和维护的问题: 非纯组件的话,可以直接省去 triggerEvent 的过程,直接修改 store.data 并且 update,形成缩减版单向数据流. Github: https://github.com/dntzhang/westore 组件 这里说的组件便是自定义组件,使用原生小程序的开发格式如下: Component({ properties: { }, data: { }, methods: { } }) 使用 Wes

网易考拉Android客户端网络模块设计

本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Square公司的OkHttp,Google推出的Volley,还有在OkHttp基础上进行封装的Retrofit等,这些都是非常优秀的网络处理框架.利用现有网络处理框架,比从零开始设计.开发网络请求节省很多开发时间,同时也避免了一些意想不到的问题.如果把这些框架直接拿来使用,不进行任何二次封装,会使我们工程

3星|考拉小巫《其实你很好》:正念缓解焦虑,接纳治疗拖延

美国心理咨询师写的,重点内容是如何缓解焦虑,如何治疗拖延.穿插着用几个作者的病人举例,说明作者如何帮助他们克服焦虑.拖延等问题. 书挺厚,有30万字,不过我感觉篇幅可以大幅压缩不影响内容表达. 另外还有一个缺陷:作者给出了一些治疗心理问题的理论与方法(显然这些理论与方法是作者自己喜欢的常用的),但是没提还有没有更好的理论与方法. 我归纳作者最重要的治疗方法是这两个: 1:正念,可以缓解焦虑: 2:接纳自己的不完美,可以逐步治疗拖延症. 读后我的感觉是这些方法看起来还不错,不过读者真想试用来解决自

coffeescript写的一个无限下拉小程序

locate=$(document).height()-$(window).height() times=0 scroller = (cb)-> if locate<=$(document).height()-$(window).height() times=0 locate+=100 scroll(0,locate) clearTimeout(timer) timer=setTimeout("scroller()",54) timer else await sleep 3

施德来:有赞电商小程序的实践

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 施德来,毕业于浙江大学计算机学院.曾任职于淘宝.网易,现任有赞前端技术负责人.电商小程序技术负责人. 因为有赞刚好在移动电商这个赛道上,整个行业都推动着我们向前走.海量的商家有各自的需求,不断地在业务上督促我们做一些事.这次我代表团队为大家汇报一下我们被商家推动着做了哪些事,主要是关于技术方面的. 我眼中的小程序 首先和大家分享一下我眼中的小程序到底是什么?关于小程序,有两大矛盾困扰着所有的移动开发者.一个是H5跨平台的开发速度很快,但