mpvue 解析
前言
mpvue是一款使用Vue.js开发微信小程序的前端框架。 总结 生命周期的理解 文档 一次前后端实践
使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力。
如果想将 H5 项目改造为小程序,或开发小程序后希望将其转换为H5,mpvue将是十分契合的一种解决方案。
目前,mpvue已经在美团点评多个实际业务项目中得到了验证,因此我们决定将其开源,希望更多技术同行一起开发,
应用到更广泛的场景里去。github项目地址请参见mpvue 。使用文档请参见 http://mpvue.com/。
为了帮助大家更好的理解mpvue的架构,接下来我们来解析框架的设计和实现思路。文中主要内容已经发表在《程序员》杂志2017年第9期小程序专题封面报道,内容略有修改。
小程序开发特点
微信小程序推荐简洁的开发方式,通过多页面聚合完成轻量的产品功能。
小程序以离线包方式下载到本地,通过微信客户端载入和启动,开发规范简洁,技术封装彻底,自成开发体系,有Native和H5的影子,但又绝不雷同。
小程序本身定位为一个简单的逻辑视图层框架,官方并不推荐用来开发复杂应用,但业务需求却难以做到精简。
复杂的应用对开发方式有较高的要求,如组件和模块化、自动构建和集成、代码复用和开发效率等,但小程序开发规范较大的限制了这部分能力。
为了解决上述问题,提供更好的开发体验,我们创造了mpvue,通过使用Vue.js来开发微信小程序。
mpvue是什么
mpvue是一套定位于开发小程序的前端开发框架,其核心目标是提高开发效率,增强开发体验。使用该框架,
开发者只需初步了解小程序开发规范、熟悉Vue.js基本语法即可上手。框架提供了完整的 Vue.js 开发体验,
开发者编写Vue.js代码,mpvue 将其解析转换为小程序并确保其正确运行。
此外,框架还通过 vue-cli 工具向开发者提供quick start 示例代码,开发者只需执行一条简单命令,即可获得可运行的项目。
为什么做mpvue
在小程序内测之初,我们计划快速迭代出一款对标 H5 的产品实现,核心诉求是:
快速实现、代码复用、低成本和高效率… 随后经历了多个小程序建设,
结合业务场景、技术选型和小程序开发方式,我们整理汇总出了开发阶段面临的主要问题:
- 组件化机制不够完善
- 代码多端复用能力欠缺
- 小程序框架和团队技术栈无法有机结合
- 小程序学习成本不够低
组件机制:小程序逻辑和视图层代码彼此分离,公共组件提取后无法聚合为单文件入口,
组件需分别在视图层和逻辑层引入,维护性差;
组件无命名空间机制,事件回调必须设置为全局函数,组件设计有命名冲突的风险,数据封装不强。
开发者需要友好的代码组织方式,通过 ES 模块一次性导入;组件数据有良好的封装。成熟的组件机制,对工程化开发至关重要。
多端复用:常见的业务场景有两类,通过已有 H5 产品改造为小程序应用或反之。
从效率角度出发,开发者希望通过复用代码完成开发,但小程序开发框架却无法做到。
我们尝试过通过静态代码分析将 H5 代码转换为小程序,但只做了视图层转换,无法带来更多收益。多端代码复用需要更成熟的解决方案。
引入 Vue.js:小程序开发方式与 H5 近似,因此我们考虑和 H5 做代码复用。
沿袭团队技术栈选型,我们将 Vue.js 确定为小程序开发规范。使用 Vue.js 开发小程序,将直接带来如下开发效率提升:
- H5 代码可以通过最小修改复用到小程序
- 使用 Vue.js 组件机制开发小程序,可实现小程序和 H5 组件复用
- 技术栈统一后小程序学习成本降低,开发者从 H5 转换到小程序不需要更多学习
- Vue.js 代码可以让所有前端直接参与开发维护
为什么是 Vue.js?这取决于团队技术栈选型,引入新的选型与统一技术栈和提高开发效率相悖,有违开发工具服务业务的初衷。
mpvue 的演进
mpvue的形成,来源于业务场景和需求,最终方案的确定,经历了三个阶段。
第一阶段:我们实现了一个视图层代码转换工具,旨在提高代码首次开发效率。
通过将H5视图层代码 转换 为小程序代码,包括 HTML 标签映射、Vue.js 模板和样式转换,在此目标代码上进行二次开发。
我们做到了 有限的代码复用 ,但组件化开发和小程序学习成本并未得到有效改善。
第二阶段:我们着眼于完善代码组件化机制。
参照 Vue.js 组件规范设计了代码组织形式,通过代码转换工具将代码解析为小程序。
转换工具主要解决组件间数据同步、生命周期关联和命名空间问题。
最终我们实现了一个 Vue.js 语法子集,但想要实现更多特性或跟随 Vue.js 版本迭代,工作量变得难以估计,有永无止境之感。
第三阶段:我们的目标是实现对 Vue.js 语法全集的支持,达到使用 Vue.js 开发小程序的目的。
并通过引入 Vue.js runtime 实现了对 Vue.js 语法的支持,从而避免了人肉语法适配。
至此,我们完成了使用 Vue.js 开发小程序的目的。
较好地实现了技术栈统一、组件化开发、多端代码复用、降低学习成本和提高开发效率的目标。
mpvue设计思路
Vue.js 和小程序都是典型的逻辑视图层框架,逻辑层和视图层之间的工作方式为:
数据变更驱动视图更新;视图交互触发事件,事件响应函数修改数据再次触发视图更新,如图1所示。
图1: 小程序实现原理
鉴于 Vue.js 和小程序一致的工作原理,我们思考将小程序的功能托管给 Vue.js,在正确的时机将数据变更同步到小程序,
从而达到开发小程序的目的。
这样,我们可以将精力聚焦在 Vue.js 上,参照 Vue.js 编写与之对应的小程序代码,
小程序负责视图层展示,所有业务逻辑收敛到 Vue.js 中,Vue.js 数据变更后同步到小程序,如图2所示。
如此一来,我们就获得了以 Vue.js 的方式开发小程序的能力。为此,我们设计的方案如下:
Vue代码
- 将小程序页面编写为 Vue.js 实现
- 以 Vue.js 开发规范实现父子组件关联
小程序代码
- 以小程序开发规范 编写视图层模板
- 配置生命周期函数,关联数据更新调用
- 将 Vue.js 数据 映射 为小程序数据模型
并在此基础上,附加如下机制
- Vue.js 实例与小程序 Page 实例建立关联
- 小程序和 Vue.js 生命周期建立映射关系,能在小程序生命周期中触发 Vue.js 生命周期
- 小程序事件建立代理机制,在事件代理函数中触发与之对应的 Vue.js 组件事件响应
这套机制总结起来非常简单,但实现却相当复杂。在揭秘具体实现之前,读者可能会有这样一些疑问:
- 要同时维护 Vue.js 和小程序,是否需要写两个版本的代码实现?
- 小程序负责视图层展现,Vue.js的视图层是否还需要,如果不需要应该如何处理?
- 生命周期如何打通,数据同步更新如何实现?
上述问题包含了 mpvue 框架的核心内容,下文将仔细为你道来。
首先,mpvue 为提高效率而生,本身提供了自动生成小程序代码的能力,小程序代码根据 Vue.js 代码构建得到,并不需要同时开发两套代码。
Vue.js 视图层渲染由 render 方法完成,同时在内存中维护着一份虚拟 DOM,mpvue 无需使用 Vue.js 完成视图层渲染,
因此我们改造了 render 方法,禁止视图层渲染。熟悉源代码的读者,都知道 Vue runtime 有多个平台的实现,
除了我们常见的 Web 平台,还有 Weex。从现在开始,我们增加了新的平台 mpvue。
生命周期关联:生命周期和数据同步是 mpvue 框架的灵魂,Vue.js 和小程序的数据彼此隔离,各自有不同的更新机制
。mpvue 从生命周期和事件回调函数切入,在 Vue.js 触发数据更新时实现数据同步。
小程序通过视图层呈现给用户、通过事件响应用户交互,Vue.js 在后台维护着数据变更和逻辑。
可以看到,数据更新发端于小程序,处理自 Vue.js,Vue.js 数据变更后再同步到小程序
。为实现数据同步,mpvue 修改了 Vue.js runtime 实现,在 Vue.js 的生命周期中增加了更新小程序数据的逻辑。
事件代理机制:用户交互触发的数据更新通过事件代理机制完成。在 Vue.js 代码中,
事件响应函数对应到组件的 method, Vue.js 自动维护了上下文环境。然而在小程序中并没有类似的机制,
又因为 Vue.js 执行环境中维护着一份实时的虚拟 DOM,这与小程序的视图层完全对应,
我们思考,在小程序组件节点上触发事件后,只要找到虚拟 DOM 上对应的节点,触发对应的事件不就完成了么;
另一方面,Vue.js 事件响应如果触发了数据更新,其生命周期函数更新将自动触发,在此函数上同步更新小程序数据,数据同步也就实现了。
mpvue如何使用
mpvue框架本身由多个npm模块构成,入口模块已经处理好依赖关系,开发者只需要执行如下代码即可完成本地项目创建。
# 安装 vue-cli
$ npm install --global vue-cli
# 根据模板项目创建本地项目,目前为内网地址
$ vue init ‘bitbucket:xxx.meituan. com:hfe/mpvue-quickstart’ --clone my- project
# 安装依赖和启动自动构建
$ cd my-project
$ npm install
$ npm run dev
执行完上述命令,在当前项目的 dist 子目录将构建出小程序目标代码,使用小程序开发者工具载入 dist 目录即可启动本地调试和预览。
示例项目遵循 Vue.js 模板项目规范,通过Vue.js 命令行工具vue-cli创建。代码组织形式与 Vue.js 官方实例保持一致,
我们为小程序定制了 Vue.js runtime 和 webpack 加载器,此部分依赖也已经内置到项目中。
针对小程序开发中常见的两类代码复用场景,mpvue 框架为开发者提供了解决思路和技术支持,
开发者只需要在此指导下进行项目配置和改造。我们内部实践了一个将 H5 转换为小程序的项目,下图为使用 mpvue 框架的转换效果:
图3: H5 和小程序转换效果
将小程序转换为H5:直接使用 Vue.js 规范开发小程序,代码本身与H5并无不同,
具体代码差异会集中在平台 Api 部分。此外并不需明显改动,改造主要分如下几部分:
- 将小程序平台的 Vue.js 框架替换为标准 Vue.js
- 将小程序平台的 vue-loader 加载器替换为标准 vue-loader
- 适配和改造小程序与 H5 的底层 Api 差异
将H5转换为小程序:已经使用 Vue.js 开发完 H5,我们需要做的事情如下:
- 将标准 Vue.js 替换为小程序平台的 Vue.js 框架
- 将标准 vue-loader 加载器替换为小程序平台的 vue-loader
- 适配和改造小程序与 H5 的底层 Api 差异
根据小程序开发平台提供的能力,我们最大程度的支持了 Vue.js 语法特性,但部分功能现阶段暂时尚未实现。
表1: mpvue 暂不支持的语法特性
项目转换注意事项:框架的目标是将小程序和 H5 的开发方式通过 Vue.js 建立关联,达到最大程度的代码复用。
但由于平台差异的客观存在(主要集中在实现机制、底层Api 能力差异),我们无法做到代码 100% 复用,
平台差异部分的改造成本无法避免。对于代码复用的场景,开发者需要重点思考如下问题并做好准备:
- 尽量使用平台无的语法特性,这部分特性无需转换和适配成本
- 避免使用不支持的语法特性,譬如 slot, filter 等,降低改造成本
- 如果使用特定平台 Api ,考虑抽象好适配层接口,通过切换底层实现完成平台转换
mpvue 最佳实践
在表2中,我们对微信小程序、mpvue、WePY 这三个开发框架的主要能力和特点做了横向对比,帮助大家了解不同框架的侧重点,
结合业务场景和开发习惯,确定技术方案。对于如何更好地使用 mpvue 进行小程序开发,我们总结了一些最佳实践。
- 使用 vue-cli 命令行工具创建项目,使用Vue 2.x 的语法规范进行开发
- 避免使用框架不支持的语法特性,部分 Vue.js语法在小程序中无法使用,尽量使用 mpvue 和 Vue.js 共有特性
- 合理设计数据模型,对数据的更新和操作做到细粒度控制,避免性能问题
- 合理使用组件化开发小程序,提高代码复用率
表2: 框架使用特点对比
结语
mpvue 框架已经在业务项目中得到实践和验证,目前正在美团点评内部大范围使用。
mpvue 来源于开源社区,饮水思源,我们也希望为开源社区贡献一份力量,为广大小程序开发者提供一套技术方案。
mpvue 的初衷是让 Vue.js 的开发者以低成本接入小程序开发,做到代码的低成本迁移和复用
,我们未来会继续扩展现有能力、解决开发者的诉求、优化使用体验、完善周边生态建设,帮助到更多的开发者。
最后,mpvue 基于 Vue.js 源码进行二次开发,新增加了小程序平台的实现,我们保留了跟随 Vue.js 版本升级的能力,
由衷的感谢 Vue.js 框架和微信小程序给业界带来的便利。
作者简介
成全:美团点评酒旅事业群资深前端工程师,目前主要从事移动端和小程序技术方向,致力于小程序的工程化开发和业务级应用。
招聘时间~美团点评酒旅业务研发中心诚招中、高级前端工程师、技术专家,欢迎投递简历到 huchengquan#meituan.com
mpvue 解析的更多相关文章
- 用Vue.js开发微信小程序:开源框架mpvue解析
前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...
- MpVue解析
前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发 ...
- 美团客户端响应式框架EasyReact开源啦
前言 EasyReact 是一款基于响应式编程范式的客户端开发框架,开发者可以使用此框架轻松地解决客户端的异步问题. 目前 EasyReact 已在美团和大众点评客户端的部分业务中进行了实践,并且持续 ...
- FCC 成都社区·前端周刊 第 3 期
01. Chrome65 的新功能 CSS Paint API 允许使用编程方式生成图像:Server Timing API允许服务器将时间信息通过HTTP headers传递给浏览器: CSS di ...
- 解密国内BAT等大厂前端技术体系-美团点评之下篇(长文建议收藏)
引言 在上篇中,我已经介绍了美团点评的业务情况.大前端的技术体系,其中大前端的技术全景图如下: 上篇重点介绍了工程化和代码质量的部分,工程化涵盖了客户端持续集成平台-MCI.全端监控平台-CAT.移动 ...
- mpvue中使用wxParse,解析a标签跳转问题
安装:npm i mpvue-wxparse js:import wxparse from "mpvue-wxparse"; css:@import url('~mpvue-wxp ...
- 适用于 Mpvue 的微信小程序富文本解析自定义组件
废话不多说,直接上方法: 首先 npm 安装 mpvue-wxparse npm i mpvue-wxparse 接下来:使用 <template> <div> <wxP ...
- 一套代码小程序&Web&Native运行的探索07——mpvue简单调研
前言 接上文:[一套代码小程序&Native&Web阶段总结篇]可以这样阅读Vue源码 最近工作比较忙,加之上个月生了小孩,小情人是各种折腾他爸妈,我们可以使用的独立时间片不多,虽然这 ...
- 使用mpvue开发小程序
前言: 最近接到小程序的开发需求,由于之前也没开发过小程序,心情还是有点激动.先花15分钟看一遍小程序官方文档,再花10分钟看一遍mpvue官方文档,然后拿着原型图和UI图就开干.踩了不少坑,写篇博客 ...
随机推荐
- Linux脚本shell字符串处理
Linux脚本shell字符串处理,基本都有了,看着搜吧 TLDP教堂 shell中if条件字符串.数字比对,[[ ]]和[ ]区别 Linux 之 shell 比较运算符 Linux Shell编程 ...
- kubernetes endpoint一会消失一会出现的问题剖析
问题现象 发现某个service的后端endpoint一会显示有后端,一会显示没有.显示没有后端,意味着后端的address被判定为notready. endpoint不正常的时候: [root@lo ...
- Android添加百分比布局库时显示Failed to resolve: com.android.support.percent:问题
这是看第一行代码中遇到的问题,要添加百分比布局库的依赖时要在app下的bulid.gradle添加以下代码 implementation fileTree(dir:'libs',include:['* ...
- 7.26-Codeforces Round #372 (Div. 2)
C. Plus and Square Root 链接:codeforces.com/group/1EzrFFyOc0/contest/716/problem/C 题型:构造 题意:起始数 x 为 2, ...
- Bootstrap3基础 page-header 标题下加分割线
内容 参数 OS Windows 10 x64 browser Firefox 65.0.2 framework Bootstrap 3.3.7 editor ...
- 缓存算法(FIFO 、LRU、LFU三种算法的区别)
FIFO算法 FIFO 算法是一种比较容易实现的算法.它的思想是先进先出(FIFO,队列),这是最简单.最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小.空间满的时 ...
- Spring Boot 2集成Redis
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.redis是一个key-value存储系统,支持存储的valu ...
- Nginx教程---03.Nginx日志切割
Nginx的定时任务与自动切割 明确: 如果这个网站的访问量比较大,那么一天下来 nginx日志可能会特别的大,所以当出现这种情况呢,如果 把每天的日志都存在同一个日志文件里,会使你的日志文件大到让你 ...
- sqlserver数据库中sql的使用
目录: 1. 分组排序更新 2. 将查询结果插入到新的表中 3. 创建/更新存储过程 4. 创建/更新视图 5. 插入数据 6. 增加表格的列 7. 创建表格 8. 创建索引 9. 递归查询 1. 分 ...
- Rancher2.0中使用外置NFS存储部署Nginx实验
目录: 1.环境准备工作 1.1 准备好Rancher2.0集群环境 1.2 准备好外部NFS服务器 2.Rancher2.0中使用NFS存储的方法 2.1 在集群中创建持久卷(PV) 2.2 在项目 ...