使用Vue.js开发微信小程序:开源框架mpvue解析

戳蓝字“CSDN云计算”关注我们哦!
640?wx_fmt=jpeg
作者 | 成全
责编 | 阿秃
转自 | 美团技术团队企业博客

前言

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所示。

640?wx_fmt=jpeg
图1:小程序实现原理

鉴于 Vue.js 和小程序一致的工作原理,我们思考将小程序的功能托管给 Vue.js,在正确的时机将数据变更同步到小程序,从而达到开发小程序的目的。这样,我们可以将精力聚焦在 Vue.js 上,参照 Vue.js 编写与之对应的小程序代码,小程序负责视图层展示,所有业务逻辑收敛到 Vue.js 中,Vue.js 数据变更后同步到小程序,如图2所示。如此一来,我们就获得了以 Vue.js 的方式开发小程序的能力。为此,我们设计的方案如下:

640?wx_fmt=jpeg
图2:mpvue 实现原理

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 框架的转换效果:

640?wx_fmt=jpeg
图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 语法特性,但部分功能现阶段暂时尚未实现。

640?wx_fmt=png
表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 共有特性
  • 合理设计数据模型,对数据的更新和操作做到细粒度控制,避免性能问题
  • 合理使用组件化开发小程序,提高代码复用率

640?wx_fmt=png
表2:框架使用特点对比

结语

mpvue 框架已经在业务项目中得到实践和验证,目前正在美团点评内部大范围使用。mpvue 来源于开源社区,饮水思源,我们也希望为开源社区贡献一份力量,为广大小程序开发者提供一套技术方案。mpvue 的初衷是让 Vue.js 的开发者以低成本接入小程序开发,做到代码的低成本迁移和复用,我们未来会继续扩展现有能力、解决开发者的诉求、优化使用体验、完善周边生态建设,帮助到更多的开发者。

最后,mpvue 基于 Vue.js 源码进行二次开发,新增加了小程序平台的实现,我们保留了跟随 Vue.js 版本升级的能力,由衷的感谢 Vue.js 框架和微信小程序给业界带来的便利。

640?wx_fmt=png

640?wx_fmt=png


640?wx_fmt=png

福利
扫描添加小编微信,备注“姓名+公司职位”,入驻【CSDN博客】,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

640?wx_fmt=jpeg

推荐阅读:
  • 【小白集合】详解服务器内存和显存基础知识
  • 【忽悠面试官就靠它了】『Spring事务管理器』源码阅读梳理
  • 如何破解焦虑成为技术大牛?资深技术 Leader 肺腑忠告

  • 快手王华彦:端上视觉技术的极致效率及其短视频应用实践 | AI ProCon 2019
  • 每个新手程序员都应该知道的Python开发技巧

  • 5G来了,智能手机们还能拼什么?

  • 揭秘!“链上FBI”Chainalysis如何追踪暗网交易?

真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521387.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高并发下Java多线程编程基础

摘要: Java线程同步与异步 线程池 无锁化的实现方案 分布锁的实现方案 分享的目的: 进一步掌握多线程编程和应用的技巧,希望对大家在平时的开发中应对高并发编程有所帮助 Java线程同步与异步 1. 同步相关的方法有 wait, notify, notifyAll 2.…

deebot扫地机器人怎么清洁_扫地机器人清洁力拼杀,科沃斯机器人DEEBOT N3与小米1S对比评测...

“偷懒是第一生产力”,这句看似玩笑的话细细品味起来似乎还是有点道理,扫地机器人产业的逐渐兴盛又一次验证科技改变人们的生活方式。我自己生活中很少有时间去清扫地面,而且我是个很容易制造垃圾的人,几天不扫家里就脏乱的无法直…

机票分享第一篇 机票由何而来

要: 遥想05年刚加入飞猪,有同学问我机票搜索是怎么做的,一时间不知如何回答。转眼三年过去,为了给自己一个交代,抽时间把所负责的业务、系统、心得加以总结,才有了这几篇机票分享的文章。由于所用的技术、架…

java 获取ip地址_老杜带你学Java【第二课】

上期链接:老杜带你学Java【第一课】01写在前面欢迎来到杜老师的「零基础学Java」课堂~今后,我们就是Java软件工程师了。(此处应该有掌声???)本专题为《零基础学Java》专题,将带你学习2020年全新Java零基础教程,由杜老师亲自录制…

【光说不练假把式】今天说一说Kubernetes 在有赞的实践

戳蓝字“CSDN云计算”关注我们哦!作者 | 木鱼 on基础保障责编 | 阿秃一、背景我们为什么选择 Kubernetes?因为 Kubernetes 几乎支持所有的容器业务类型,包括无状态应用、有状态应用、任务型和 Daemonset,Kubernetes 也逐渐成为容…

Apache旗下顶级开源盛会 HBasecon Asia 2018将于8月在京举行

摘要: 作为Apache基金会旗下HBase社区的顶级用户峰会,HBaseCon大会是Apache HBase™官方从2012年开始发起和延续至今的技术会议,先后在美国加州、日本东京和中国深圳等地举办,得到了Google、Facebook、雅虎和阿里巴巴等众多全球顶…

r语言查找是否存在空值_关于R包安装你知道多少?

在R语言的学习过程中离不了各种R包的安装与使用,要使用某个R包首先得学会如何安装该R包。对于R包的安装你知道的有多少?你知道如何指定安装路径吗?为何你每次重新打开R绘画都需要重新安装R包?今天小编带你详细理解install.package…

深入理解JAVA虚拟机学习笔记(一)JVM内存模型

摘要: 上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了。这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状…

oracle schema_了解Oracle备份恢复的知识

Oracle架构体系警报日志(alter log):一个文本日志文件,记录数据库的错误和状态信息,通常情况下,警报日志位于后台转存目标目录中,该目录有数据库参数DIAFNOSTIC_DEST定义的,其中警报日志的格式为alter.log。…

美部长施压堵华为,遭印度电信巨头现场驳斥 ;WhatsApp被曝漏洞:仅凭一张GIF动图黑客便可接管账户……...

关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周三次,打卡即read更快、更全了解泛云圈精彩newsgo go go 每周三次,打卡即…

实现Chrome Devtools调试JavaScript V8引擎

摘要: 最近开发小程序JavaScript的运行时,通过在客户端嵌入JavaScript V8引擎来实现。前端同学需要调试JavaScript代码,正好Chrome浏览器的Devtools是与V8的Inspector调试协议是一脉相承的,理论上是可以使用Chrome Devtools调试Ja…

angular7.2构建包如何兼容ie_Python 小技巧:如何实现操作系统兼容性打包?

转自:Python猫有一个这样的问题:现要用 setuptools 把一个项目打包成 whl 文件,然后 pip install 在 Windows/Linux 两种操作系统上,但是该项目中有一些依赖库只有 Windows 上才有(例如 pywinauto、pywingui、pywinrm)&#xff0c…

阿里云ET工业大脑发布AI视觉产品“见远”:电池片、车辆、路面都能被“诊断”

摘要: 7月24日,阿里云ET工业大脑发布AI视觉产品“见远“,可以利用深度学习和图像处理算法,自动识别图像中的瑕疵、故障及其他目标物,大幅节省人力,提高产品生产效率及精度稳定性效果。 7月24日&#xff0c…

最后2天,BDTC 2019 早鸟票即将售罄,超强阵容及议题抢先曝光!

大会官网:https://t.csdnimg.cn/U1wA2019 年12月5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会,将于北京长城饭店隆重举行。届时&#xf…

利用python做一个小游戏_如何使用python做一个简单的猜数字的小游戏

1 首先小编先打开IDLE,如下图:2 然后这里点击菜单栏的File,然后点击菜单"New File",如下图:3 然后我们就在idle中新建了一个python文件,如下图:4 在这里我们按照下图中代码输入到文件…

阿里HBase的数据管道设施实践与演进

摘要: 大数据生态下有着丰富多样的系统:流计算,数据存储,实时分析,离线计算,数据在各个异构系统之间的流转和加工而产生价值,高效的数据传输通道是大数据生态的重要一环。本文描述了阿里HBase团…

gradle官方文档_Spring Boot+Gradle+MyBatisPlus3.x搭建企业级的后台分离框架

你再主动一点点 我们就有故事了原文:toutiao.com/i68614564967402706041、技术选型解析器:FastJSON开发工具:JDK1.8 、Gradle、IDEA技术框架:SpringBoot 2.1.5.RELEASEORM技术:MyBatisPlus3.1.2数据库:My…

java random用法_JAVA面试题(1)

1.Java内部类和子类之间有什么区别?答案:内部类是指在一个外部类的内部再定义一个类,内部类对外部类有访问权限,可以访问类 中定义的所有变量和方法。子类是从父类(superclass)中继承的类,子类可以访问父类所有public和…

【不了解你就OUT了】云原生基本原则

戳蓝字“CSDN云计算”关注我们哦!作者 | 架构师技术联盟责编 | 阿秃云原生指的是一个敏捷的工程团队,遵循敏捷的研发原则,使用高度自动化的研发工具,开发基于云基础设施和服务的应用以满足快速变化的客户需求。这些应用采用弹性&…