整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

一周开发 6 个版本,小程序多端框架深入测评 - 程序员硬核评测

者 | uni-app团队

责编 | 伍杏玲

【CSDN 编者按】最近前端界多端框架频出,各巨头公司纷纷造出各家的轮子,那么开发者该怎么选呢?

为了让开发者能直观地感受每个框架的差异,uni-app团队投入一周真实地开发了6个框架的小程序,从性能、跨端支持、学习门槛、工具等多方面进行深度评测,一起来看看他们的研究结果吧。

之前Taro团队发布了一篇

小程序多端框架全面测评

,让开发者对业界主流的跨端框架,有了初步认识,感谢Taro团队的付出。不过横评这件事,要想得到更精确的结论,其实非常花费时间。它需要:

真实地动手写多个平台的测试Demo,比较各个平台的功能、性能,它们的实际情况到底是不是如文档所写?

真实地学习每个框架,了解它们的学习曲线,在实际开发中遇到问题时,感受它们的文档、教程、社区生态和技服能力到底怎么样?

我们 uni-app 团队投入一周完成了这个深度评测,下面我们分享下实际开发不同框架的测试例时遇到的问题,以及在各端的兼容测试结果。在本文里,我们团队基于真实测试数据及各框架官网可采集到的公开数据,希望客观公正地评价各个框架的选型和优劣。但宥于利益相关,本文的观点很可能是带有偏向性的,大家可以带着批判的眼光去看待。

评测实验介绍

开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。

开发版本:一共开发了6个版本,包括微信原生版、WePY版、Mpvue版、Taro版、uni-app版、Chameleon版(以这些产品发布时间排序,下同),按照官网指引通过cli方式默认安装。

测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版(最新版)、微信版本 7.0.3(最新版)。

测试环境:每个框架开始测试前,杀掉各App进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差异。

测试维度:

  1. 跨端支持度如何?
  2. 性能如何?
  3. 学习门槛。
  4. 工具与周边生态。

测试界面:

跨端支持度如何

开发一次,到处运行,是每个程序员的梦想。但现实往往变成开发一次,到处调错。

各个待评测框架,是否真得如官宣的那样,一次开发、多端发布?

我们将上述仿微博App依次发布到各平台,验证每个框架在各端的兼容性,结果如下:

测试结果说明:

  • ⭕ 表示支持且功能正常,❌ 表示不支持,其它则表示支持但存在部分Bug或兼容问题。
  • WePY 2.0 官宣已支持其他家小程序,本测试基于WePY官网指引安装的wepy-cli默认版本为1.7.3,尚不支持多端。
  • chameleon官网未找到stopPullDownRefresh定义,停止页面下拉刷新需分平台编写。

通过上述例子可以看出,跨端支持度测评结论:uni-app > Taro > Chameleon > Mpvue >WePY、原生微信小程序

但是仅有上面的测试还不全面,实际业务要比这个测试例复杂很多。但我们没法开发很多复杂业务做评测,所以还需要再对照各家文档补充一些信息。

由于每个框架的文档中都描述了各种组件和API的跨端支持程度。我们过了几家的文档,发现各家基本是以微信小程序为基线,然后把各种组件和API在其他端实现了一遍:

  • Taro:H5端实现了大部分微信的API,App端和微信的差异比较大。
  • uni-app:组件、API、配置,大部分在各个端均已实现,个别API有说明在某些端不支持。可以看出uni-app是完整在H5端实现了一套微信模拟器,在App端实现了一套微信小程序引擎,才达到比较完善的平台兼容性。
  • Chameleon:常用的一些组件和API在各端已经实现,这部分的平台差异较少。但大量组件和API需要开发者自己分平台写代码。

跨端框架,一方面要考虑框架提供的通用API跨端支持,同时还要考虑不同端的特色差异如何兼容。毕竟每个端都会有自己的特色,不可能完全一致。

  • Taro:提供了JavaScript环境变量判断和统一接口的多端文件,可以在组件、JavaScript、文件方面扩展多端,不支持其他环节的分平台处理。
  • uni-app:提供了条件编译模型,所有代码包括组件、JavaScript、CSS、配置Json、文件、目录,均支持条件编译,可不受限的编写各端差异代码。
  • Chameleon:提供了多态方案,可以在组件、JavaScript、文件方面扩展多端,不支持其他方式的分平台处理。

跨端框架,还涉及一个UI框架的跨端问题,评测结果如下:

  • Taro:官方提供了Taro UI,支持小程序(微信/支付宝/百度)、H5平台,不支持App。
  • uni-app:官方提供了Uni UI,可全端运行;uni-app还有一个插件市场,里面有很多三方UI组件。
  • Chameleon:官方提供了cml-ui扩展组件库,可全端运行,但组件数量略少。

最后补充跨端案例:

  • Mpvue:微信端案例丰富,未见其它端案例。
  • Taro:微信端案例丰富,百度、支付宝、H5端亦有少量案例。
  • uni-app:微信、App、H5三端案例丰富,官方示例已发布到6端。
  • Chameleon:未看到任何端案例。

综合以上信息,本项的最终评测结论:uni-app > Taro > Chameleon > Mpvue > WePY、原生微信小程序

跨端框架性能如何

跨端框架基本都是Compiler + Runtime模式,引入的Runtime是否会降低运行性能?

尤其是与原生微信小程序开发相比性能怎么样,这是大家普遍关心的问题。

我们依然以上述仿微博小程序为例,测试2个容易出性能问题的点:长列表加载、大量点赞组件的响应。

长列表加载

仿微博的列表是一个包含很多组件的列表,这种复杂列表对性能的压力更大,很适合做性能测试。

从触发上拉加载到数据更新、页面渲染完成,需要准确计时。人眼视觉计时肯定不行,我们采用程序埋点的方式,制定了如下计时时机:

  1. 计时开始时机:交互事件触发,框架赋值之前,如:上拉加载(onReachBottom)函数开头
  2. 计时结束时机:页面渲染完毕(微信setData回调函数开头)

Tips:setData回调函数开头可认为是页面渲染完成的时间,是因为微信setData定义如下(微信规范):

测试方式:从页面空列表开始,通过程序自动触发上拉加载,每次新增20条列表,记录单次耗时;固定间隔连续触发 N 次上拉加载,使得页面达到 20*N 条列表,计算这 N 次触发上拉 -> 渲染完成的平均耗时。

测试结果如下:

说明:以400条微博列表为例,从页面空列表开始,每隔1秒触发一次上拉加载(新增20条微博),记录单次耗时,触发20次后停止(页面达到400条微博),计算这20次的平均耗时,结果微信原生在这20次触发上拉 -> 渲染完成的平均耗时为876毫秒,最快的uni-app是741毫秒,最慢的Mpvue是4493毫秒。

大家初看这个数据,可能比较疑惑,别急,下方有详细说明。

说明1:为何 Mpvue/WePY 测试数据不完整?

Mpvue、WePY 诞生之初,微信小程序尚不支持自定义组件,无法进行组件化开发;Mpvue、WePY 为解决这个问题,将用户编写的Vue组件,编译为WXML中的模板,变相实现了组件化开发能力,提高代码复用性,这在当时的技术条件下是很棒的技术方案。

但如此方案,在复杂组件较多的页面,会大量增加 Dom 节点数量,甚至超出微信的 dom 节点数限制。我们在红米手机(Redmi 6 Pro)上实测,页面组件超过500个时,Mpvue、WePY 实现的仿微博App就会报出如下异常,并停止渲染,故这两个测试框架在组件较多时,测试数据不完整。这也就意味着,当页面组件太多时,无法使用这2个框架。

dom limit exceeded please check if there’s any mistake you’ve made

Tips:WePY在400条列表以内,为何性能高于微信原生框架,这个跟自定义组件管理开销及业务场景有关(WePY编译为模板,不涉及组件创建及管理开销),后续对微博点赞,涉及组件数据传递时,微信原生框架的性能优势就提现出来了,详见下方测试数据。

说明2:为什么测试数据显示uni-app会比微信原生框架性能略好?

其实,在页面上有200条记录(200个组件)时,Taro 性能数据也比微信原生框架更好。

微信原生框架耗时主要在setData调用上,开发者若不单独优化,则每次都会传递大量数据;而 uni-app、Taro 都在调用setData之前自动做Diff计算,每次仅传递有变化的数据。

例如当前页面有20条数据,触发上拉加载时,会新加载20条数据,此时原生框架通过如下代码测试时,setData会传输40条数据。

data: {
 listData: []
},
onReachBottom() { //上拉加载
 let listData = this.data.listData;
 listData.push(...Api.getNews());//新增数据
 this.setData({
 listData
 }) //全量数据,发送数据到视图层
}

开发者使用微信原生框架,完全可以自己优化,精简传递数据,比如修改如下:

data: {
 listData: []
},
onReachBottom() { //上拉加载
 // 通过长度获取下一次渲染的索引
 let index = this.data.listData.length;
 let newData = {}; //新变更数据
 Api.getNews().forEach((item) => {
 newData['listData[' + (index++) + ']'] = item //赋值,索引递增
 }) 
 this.setData(newData) //增量数据,发送数据到视图层
}

经过如上优化修改后,再次测试,微信原生框架性能数据如下:

从测试结果可看出,经过开发者手动优化,微信原生框架可达到更好的性能,但 uni-app、Taro 相比微信原生,性能差距并不大。

这个结果和Web开发类似,Web开发也有原生JS开发、Vue、React框架等情况。如果不做特殊优化,原生JS写的网页,性能经常还不如Vue、React框架的性能。

也恰恰是因为Vue、React框架的开发体验好,所以原生JS开发已经逐渐减少使用了。

复杂长列表加载下一页评测结论:微信原生开发手工优化,uni-app>微信原生开发未手工优化,Taro > Chameleon > WePY > Mpvue

点赞组件响应速度

长列表中的某个组件,比如点赞组件,点击时是否能及时的修改未赞和已赞状态?

测试方式:

  • 选中某微博,点击“点赞”按钮,实现点赞状态状态切换(已赞高亮、未赞灰色),
  • 点赞按钮onclick函数开头开始计时,setData回调函数开头结束计时;

在红米手机(Redmi 6 Pro)上进行多次测试,求其平均值,结果如下:

说明:也就是在列表数量为400时,微信原生开发的应用,点赞按钮从点击到状态变化需要111毫秒。

测试结果数据说明:

  • Wepy/Mpvue测试数据不完整的原因同上,在组件较多时,页面已经不再渲染了。
  • 基于微信自定义组件实现组件开发的框架(uni-app/Taro/Chameleon),组件数据通讯性能接近于微信原生框架,远高于基于Template实现组件开发的框架(WePY/Mpvue)性能。

组件数据更新性能测评:微信原生开发,uni-app,Taro > Chameleon > WePY > Mpvue

综上,本性能测试做了2个测试,长列表加载和组件状态更新。综合2个实验,结论如下:

微信原生开发手工优化,uni-app>微信原生开发未手工优化,Taro > Chameleon > WePY > Mpvue

学习门槛

DSL语法支持度

主流跨端框架基本都遵循React、Vue(类Vue)语法,其主要目的:复用工程师的现有技术栈,降低学习成本。此时,跨端框架对于原框架(React/Vue)语法的支持度就是一个重要的衡量标准,如果支持度较低、和原框架语法差异较大,则开发者无异于要学习一门新的框架,成本太高。

实际开发中发现,各个多端框架,都没有完全实现Vue、React在Web上的所有语法:

Taro对于JS 的语法支持是相对完善的,其文档中描述未来版本计划:

更多的 JSX语法支持,1.3之后限制生产力的语法只有只能用map创造循环组件一条

Mpvue、uni-app框架基于Vue.js核心,通过修改Vue.js的Runtime和Compiler,实现了在小程序端的运行,支持绝大部分的Vue语法;uni-app编译到微信端曾经使用过Mpvue,但后来重写框架,支持了更多vue语法如Filter、复杂JavaScript表达式等。

WePY、Chameleon 都是类Vue的实现,仅支持Vue的部分语法,开发时需要单独学习它们的规则;

DSL语法支持评测:Taro,uni-app > Mpvue > WePY,Chameleon

学习资料完善度

官方文档、搜索系统的完备度方面(详见各官网):

  • WePY:文档只有2页,也无需搜索。仅支持微信,所以组件API等文档都直接看微信的文档。没有提供示例Demo。
  • Mpvue:文档较少,但其概念不复杂,也没有支持H5、App,所以组件API等文档都直接看微信的文档,学习难度低。问题搜索效果一般。没有提供示例Demo。
  • Taro:基础API文档完整,具体使用问题资源较少,问题搜索效果一般,示例Demo只包含基础功能,仅发布了微信一端。
  • uni-app:基础文档和各种使用专题内容丰富,问题搜索效果较好,示例Demo功能完备,并发布为7端上线。
  • Chameleon:基础API文档完整,具体使用问题资源较少,问题搜索效果一般,示例Demo只包含基础功能,仅发布了微信一端。

教程方面:

学习资料完善度评测:uni-app > Mpvue,Taro > Chameleon > WePY

技术支持和社区活跃度

开发难免遇到问题,官方技术支持和社区活跃度很重要。

本次评测Demo开发期间,我们的同学(同时掌握Vue和React),在学习研究各个多端框架时,切实感受到由于语法、学习资料、社区的差异带来的学习门槛。

综合评估,本项评测结论:uni-app > Taro > Mpvue > WePY > Chameleon

Tips:本测评忽略React、Vue两框架自身的学习门槛

工具和周边生态

工具

所有多端框架均支持cli模式,可以在主流前端工具中开发。

各框架基本都带有d.ts的语法提示库。

由于Mpvue、uni-app、Taro直接支持Vue、React语法,配套的IDE工具链较丰富,着色、校验、格式化完善,Chameleon针对部分编辑器推荐了插件,WePY有一些三方维护的Vscode插件。

工具属性维度,uni-app比较好,其出品公司同时也是HBuilder的出品公司,DCloud.io。

HBuilder/HBuilderX系列是四大主流前端开发工具(可对比百度指数),为uni-app做了很多优化,故uni-app的开发效率、易用性非其他框架可及。

当然对于不习惯HBuilderX的开发者而言,uni-app的这个优势无法体现。

周边生态

一个底层框架,其周边配套非常重要,比如UI库、JS库、项目模板。

WePY:出现时间久,开源项目多,占据一定优势。

Mpvue:发布时间也较早,历史积累较多。

Taro:官方提供了Taro UI,GitHub上有一些开源项目。

uni-app:提供了插件市场,UI库、周边模板丰富

Chameleon:还没有形成周边生态。

值得注意的是,uni-app和Mpvue的插件生态是互通的,都是Vue插件。所以双方还联合举办了插件大赛。这个联合生态的周边丰富度,是目前各个框架中最丰富的。

综上比较,工具和周边生态评测结论:uni-app,Mpvue > WePY > Taro > Chameleon

其他常见评测指标

GitHub Star:

GitHub Star 数对比:Taro > Wepy > Mpvue > uni-app > Chameleon

(Star数采集时间:2019.04.08 16:30)

百度指数

百度指数代表了开发者的搜索量和包含关键字的网页数量。如下是各跨端框架近7天(2019-03-24 ~ 2019-03-30)的百度指数:

WePY未被百度指数收录,说明其搜索量和包含该关键字的网页数量都不够多。

案例

仅看发布到微信小程序的案例,数量和质量综合对比,WePY > Mpvue > Taro , uni-app > Chameleon

如果看多端案例,综合对比,uni-app > Taro > Mpvue > Wepy > Chameleon

  • Wepy:的知名案例较多,包括很多一线互联网公司。
  • Mpvue、Taro:跨端框架的出品方本身为一线互联网公司,其内部项目会使用这些框架,经受过实战考验。除内部项目外,暂无其他一线互联网公司使用。
  • uni-app:案例很多,官方数据已经超过10w+。但以创业者和政企单位为主,暂无一线开发者使用。
  • Chameleon:未找到案例,无法参与本评测。

其他补充说明

App侧的补充说明

目前有Taro、uni-app、Chameleon三家框架支持App端。但在App端大多是三方产品,比如Taro使用expo(一个基于React Native的封装库),Chameleon使用Weex。

不管React Native还是Weex,其架构与小程序架构完全不同,从排版到API能力都差别很大,所以这类产品跨App端时兼容性较差。

uni-app的App端,内置一个完整小程序引擎,并补充了可选的Weex引擎。这也是uni-app在App端能够正常运行微信小程序代码的原因。

整个业内目前还不存在一个完全开源的小程序引擎(微信、百度、支付宝、头条的小程序引擎源码均未开源)。uni-app的小程序引擎不是全开源,而是能力层开源,中控未开源。

所以可能各家的多端框架,在App端都有不完美的地方,需要开发者使用时注意。

其实App引擎并非前端领域,是原生领域的另一个竞技场。

转换和混写

Taro提供了原生小程序转换为Taro工程的转换器,也支持在原生小程序里部分页面嵌入Taro编写的页面。这是Taro的特色,其他跨端框架没有提供。这对于降低入门门槛有不少帮助。

结语

真实客观的永远是实验和数据,而不是结论。不同需求的开发者,可以根据上述实验数据,自行得出自己的选型结论。

但作为一篇完整的评测,我们也必须提供一份总结,虽然它可能加入了我们的主观感受:

如果你只开发微信小程序,不做多端,那么使用微信原生开发、uni-app、Taro是更优的选择。

如果使用微信原生开发,需要注意手动写优化代码来控制setData。

如果你是React系,那就用Taro。

如果是Vue系,那就用uni-app,uni-app在性能、周边生态和开发效率上更有优势。

如果你主要为了各家小程序,且不用复杂组件,那除了uni-app和Taro,Mpvue也是不错的选择。Mpvue发布2.0版本后,搜索指数明显爬升,希望能持续更新,迎来二次繁荣。

如果你主要为了微信端和H5端,那么uni-app和Taro都可以。可以根据自己熟悉的技术栈选择。

如果你只关心App,不关心小程序和H5,那欢迎关注我们后续的评测:uni-app和Cordova、React Native、Weex、Flutter的深度比较。

Chameleon发布时间还短,完善度不如其他框架,但其未来的规划比较令人期待,值得关注。

作者:uni-app团队,即DCloud团队,专注服务中国的前端开发者,已发布产品包括:前端IDE(HBuilder/HBuilderX)、前端ui库(mui)、跨平台App引擎(HTML5Plus)、多端框架(uni-app)。

测试代码:

GitHub:https://github.com/dcloudio/test-framework

原文:https://blog.csdn.net/hbcui1984/article/details/88945790

声明:本文系作者投稿,版权归作者所有。

.前后端分离

既然我们在开发中使用前后端分离模式,也就是前端拿到后端的数据时怎么处理,怎么输出都有前端自己来实现,这样就需要写大量的js代码,而为了简化js的代码,就衍生出了很多的框架,比如jquery,Angular,Vue,React等。

二 Vue.js介绍

1.什么是Vue.js

Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。核心是一个响应的数据绑定系统。

2.Vue的特点

2.1 响应式编程

当数据发生改变时,自动更新视图。

2.2 组件化

​ UI页面映射出一个组件树
​ 组件可重用,可维护性好。

3.Vue的优势

​ vue是轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快。

​ 而且vue是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和dom,这样大大加快了访问速度和提升用户体验。而且他的第三方ui库很多节省开发时间。

4.Vue的响应式原理(MVVM)

​ Vue有一个重要特点是当数据发生变化时,可以自动更新视图,那这个是怎么实现的。这是因为Vue采用了MVVM架构模式。那什么是MVVM呢。

4.1MVC和MVVM结构对比

​ MVC模式结构图

​ MVVM模式结构图

可以看到MVVM是一个MVC的增强版,正式连接了视图和模型,将表示逻辑从Controller移出放到一个新的对象里,即ViewModel。它实现了View和Model的自动同步,即当Model的属性改变时,我们不用再自己手动操作Dom元素来改变View的显示,而是改变属性后该属性对应的View层显示会自动改变。

4.2 MVVM的组成部分

1.View

 View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建,为了更方便地展现 ViewModel 或者 Model 层的数据,已经产生了各种各样的前后端模板语言,比如 FreeMarker、Thymeleaf 等等,各大 MVVM 框架如 Vue.js,AngularJS,EJS 等也都有自己用来构建用户界面的内置模板语言。

2.Model

Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的 接口规则

3.ViewModel

ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。

需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的.

比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示);

页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互).

视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。由于实现了双向绑定,ViewModel 的内容会实时展现在 View 层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图。

MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护 ViewModel,更新数据视图就会自动得到相应更新,真正实现 事件驱动编程。

View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。

三 Vue.js基础语法

1 下载

​ 方式1:

​ Vue官网下载:https://cn.vuejs.org/v2/guide/installation.html

2 第一个入门程序

​ 开发Vue的工具很多,这里我们先使用之前讲解web前端时使用的工具Hbuilder

​ Vue.js 的核心是实现了 MVVM 模式,它扮演的角色就是 ViewModel 层,那么我们的第一个应用程序就是展示她的 数据绑定 功能,操作流程如下:

2.1 在Hbuilder中创建一个web项目

创建出来的项目结构如下:

2.2 导入Vue.js

2.3 创建一个Vue实例 ,并将数据绑定到div中

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript" src="js/vue.js" ></script>
	</head>
	<body>
		
		<div id="d1">
			{{message}}
		</div>
		
		<script type="text/javascript">
			
			var v=new Vue({
				
				el:'#d1',  //注意 这里el里面的是字符l 不是数字1   d1是上面div的id号 
				data:{
					message:'Hello Daimenglaoshi'  //初始数据
				}
				
			})			
			
			
		</script>		
		
	</body>
</html>

说明

new Vue:创建vue对象,里面的el和data是属性。

el:'#d1':绑定元素的 ID;

data:{message:'Hello Daimenglaoshi!'}:数据对象中有一个名为 `message` 的属性,并设置了初始值

{{message}}:在绑定的元素中使用 双花括号 将Vue创建的名为 message 属性包裹起来,即可实现数据绑定功能。不需要自己写js赋值。

2.4 运行测试

2.5 测试Vue的自动更新功能

​ Vue可以做到当数据发生改变时,自动更新视图

说明:


小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。组件化编程的精髓是高内聚低耦合的复用机制,这对任意一家平台开发商而言都是降低成本和保证高质量运营的关键。



小程序组件化编程有什么特点


◐ 封装粒度小于页面,是特定业务面(Business Aspects)的封装器

一个自定义组件由 json wxml wxss js 4个文件组成,分别代表声明、模板、样式和逻辑,这点和页面相同,组件声明的格式如下:

json文件

{
  "component": true
}

wxml文件

<!-- 这是自定义组件的内部 WXML 结构 -->
<view class="inner">
  {{innerText}}
</view>
<slot></slot>

vue玩家这里很熟悉吧,有一个分发槽,干什么的我就不用说了[大笑]


wxss文件

/* 这里的样式只应用于这个自定义组件 */
.inner {
  color: red;
}


js文件

//构造器
Component({
    properties: {
      // 这里定义了 innerText 属性,属性值可以在组件使用时指定
      innerText: {
        type: String,
        value: 'default value',
      }
    },
    // 私有数据,可用于模板渲染
    data: {
      // 这里是一些组件内部数据
      someData: {}
    },
    methods: {
      // 这里是一个自定义方法
      customMethod: function(){}
    },
    //公用的代码段,面向面的编程,比如加载、销毁时的log等
    behaviors: [],
    //组件生命周期
    lifetimes:{

    },
    //组件所在页面生命周期
    pageLifetimes:{

    }
  })
  


引用组件时,需在引用页面或组件的json文件中声明

{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}


usingComponents会触发Components构造器的调用,因此,我们如果把页面也作为特殊的组件,则可以通过引入usingComponents和Components的方式使页面组件化,这样会潜在的带来很多好处,比如:如访问页面 /pages/index/index?paramA=123¶mB=xyz ,如果声明有属性 paramA 或 paramB ,则它们会被赋值为 123 或 xyz,如此等等吧。



◐ 组件属性、数据的使用和通讯

组件化方法是自治策略的应用,因此,组件机制应解决数据传入、自身渲染和上下文数据通讯的问题,在微信小程序里,其分别的实现机制如下:


【1】数据传递和Vue机制类似,父传子通过properties,子传父通过子组件触发事件来完成,触发事件须使用triggerEvent 方法,指定事件名、detail对象和事件选项,如下例:

Component({
  properties: {},
  methods: {
    onTap: function(){
      var myEventDetail = {} // detail对象,提供给事件监听函数
      var myEventOption = {} // 触发事件的选项
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})


除了上述两种情况,还有父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法,爱怎么玩怎么玩。但这里要注意,调用时需要传入一个匹配选择器 selector,如:this.selectComponent(".my-component")。


【2】组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。其中,最重要的周期事件是 created、attached、detached ,包含一个组件实例生命流程的最主要时间点。组件的生命周期对应事件写在组件构造器的lifetimes对象里。


Component({
  lifetimes: {
    attached: function() {
      // 在组件实例进入页面节点树时执行
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
    },
  },
  // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
  attached: function() {
    // 在组件实例进入页面节点树时执行
  },
  detached: function() {
    // 在组件实例被从页面节点树移除时执行
  },
  // ...
})


组件关联页面的跟踪和监控写在pageLifetimes里。

Component({
  pageLifetimes: {
    show: function() {
      // 页面被展示
    },
    hide: function() {
      // 页面被隐藏
    },
    resize: function(size) {
      // 页面尺寸变化
    }
  }
})






组件的数据监听机制

组件通过 observers对象提供vue中类似watch的功能以实现数据监听,在MVVM模型中,数据的变化驱动事件产生必须有数据监听机制才行,这里不废话了,上个例子。


Component({
  observers: {
    'some.subfield': function(subfield) {
      // 使用 setData 设置 this.data.some.subfield 时触发
      // (除此以外,使用 setData 设置 this.data.some 也会触发)
      subfield === this.data.some.subfield
    },
    'arr[12]': function(arr12) {
      // 使用 setData 设置 this.data.arr[12] 时触发
      // (除此以外,使用 setData 设置 this.data.arr 也会触发)
      arr12 === this.data.arr[12]
    },
       'numberA, numberB': function(numberA, numberB) {
      // 在 numberA 或者 numberB 被设置时,执行这个函数
      this.setData({
        sum: numberA + numberB
      })
    }
  }
})






小程序开发的最佳实践

◐ 模块化

可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。

// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

在需要使用这些模块的文件中,使用 require 将公共代码引入

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})


◐ 避免异常

出现 JavaScript 异常、网络异常可能导致程序的交互无法进行下去,我们应当追求异常对正常交互的干扰,保证程序的高鲁棒性和高可用性。


◐ 不使用废弃接口

使用即将废弃或已废弃接口,可能导致小程序运行不正常。一般而言,接口不会立即去掉,但保险起见,建议不要使用,避免后续小程序突然运行异常。不要使用任何文档中提示废弃的接口。



◐ 避免setData数据冗余

setData操作会引起框架处理一些渲染界面相关的工作,一个未绑定的变量意味着与界面渲染无关,传入setData会造成不必要的性能消耗。因此,setData传入的所有数据在模板渲染中都要有相关依赖。



◐ 最低基础库版本

当使用的组件/API 的支持版本大于配置的线上最低基础库版本时,可能导致相应功能不可用。开发者可通过调整最低基础库版本或在代码上兼容的方式解决该问题。不要存在使用的组件/API 的支持版本大于配置的线上最低基础库版本的情况。



◐ 移除不可访问到的页面

小程序的包大小会影响加载时间,应该尽量控制包体积大小,避免将不会被使用的文件打包进去。存在访问不到的页面被打包到小程序中



◐ 及时回收定时器

定时器是全局的,并不是跟页面绑定的,当小程序从一个页面路由到另一个页面之后,前一个页面定时器应注意手动回收。因此,确保所有定时器的回调执行时,所在的页面都与设置定时器的页面一致。


结合前面一片的小程序开发,现在相信马上可以开始干活了,小程序是一个相对完整的封闭开发环境,和VUE、HBuilderX的uni-app等还是存在差异的,使用时多摸索多学习,相信一定会开发出令人眼前一亮的小程序。最后,还是那句话,打赏打赏。




#头条创作挑战赛#