俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

小程序开发实践总结

Taro

Taro是由京东团队开源的一套遵循 React 语法规范的多端开发解决方案。本身我对React和Taro都不是很了解,就不多解释了。具体可以看开发团队的博客和代码了解更多细节多端统一开发框架 – Taro
图片 1

request请求

wepy对wx.request做了接受参数的修改,值得一提的是它提供了针对全局的intercapter拦截器。

图片 2

拦截器

图片 3

taro对request进行了二次封装,可以使用Taro.request发起网络请求,支持 Promise 化使用。

图片 4图片 5图片 6

mpvue没有对request做特殊优化,与原生相同,可以自己根据需要进行封装

多webview架构

多webview的页面架构,小程序每新开一个页面,都会用一个新的webview来渲染。为了防止webview对内存的消耗。小程序限制层级不能超过10层。

图片 7

那些年我们踩过的坑

  • css样式不能引用本地图片资源,只能引用线上资源(background-image),引用本地图片资源只能用<image>标签。
  • {{}}不能执行函数方法,{{}}只支持基本的简单运算和ES6拓展运算符。如价格格式化这种常用的处理,只能在js代码中处理好然后再模板中渲染。
JavaScript

this.setData({ price: this.formatPrice(this.data.price) })

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e5286f536526954-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5286f536526954-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e5286f536526954-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e5286f536526954-1" class="crayon-line">
this.setData({
</div>
<div id="crayon-5b8f634e5286f536526954-2" class="crayon-line crayon-striped-line">
 price: this.formatPrice(this.data.price)
</div>
<div id="crayon-5b8f634e5286f536526954-3" class="crayon-line">
})
</div>
</div></td>
</tr>
</tbody>
</table>
  • 可以通过wxs模块解决{{}}中不能执行函数的问题。可以做到模拟vue.js中过滤器的功能。
JavaScript

&lt;!-- wxml模板 --&gt; &lt;wxs src="../../modules/formatPrice.wxs"
module="tools" /&gt;
&lt;view&gt;价格:{{tools.formatPrice(price)}}&lt;/view&gt; //
wxs模块 var formatPrice = function (price){ price = price &gt;&gt;
0; return Number(price / 100).toFixed(2); } module.exports = {
formatPrice }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-13">
13
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e52877119487867-1" class="crayon-line">
&lt;!-- wxml模板 --&gt;
</div>
<div id="crayon-5b8f634e52877119487867-2" class="crayon-line crayon-striped-line">
&lt;wxs src=&quot;../../modules/formatPrice.wxs&quot; module=&quot;tools&quot; /&gt;
</div>
<div id="crayon-5b8f634e52877119487867-3" class="crayon-line">
 
</div>
<div id="crayon-5b8f634e52877119487867-4" class="crayon-line crayon-striped-line">
&lt;view&gt;价格:{{tools.formatPrice(price)}}&lt;/view&gt;
</div>
<div id="crayon-5b8f634e52877119487867-5" class="crayon-line">
// wxs模块
</div>
<div id="crayon-5b8f634e52877119487867-6" class="crayon-line crayon-striped-line">
var formatPrice = function (price){
</div>
<div id="crayon-5b8f634e52877119487867-7" class="crayon-line">
    price = price &gt;&gt; 0;
</div>
<div id="crayon-5b8f634e52877119487867-8" class="crayon-line crayon-striped-line">
    return Number(price / 100).toFixed(2);
</div>
<div id="crayon-5b8f634e52877119487867-9" class="crayon-line">
}
</div>
<div id="crayon-5b8f634e52877119487867-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f634e52877119487867-11" class="crayon-line">
module.exports = {
</div>
<div id="crayon-5b8f634e52877119487867-12" class="crayon-line crayon-striped-line">
    formatPrice
</div>
<div id="crayon-5b8f634e52877119487867-13" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  • 小程序不支持分享链接到朋友圈,暂时的通用做法是生成保存有页面小程序码的图片到本地相册。又用户自行发朋友圈转发。前端可以利用canvas来实现,减轻服务端压力。但是会有图片锯齿不清晰的问题。建议预览图和保存到真机的图片采用不同的尺寸。保存在真机的图片按照750的宽度实现。相比于预览图要大一些,这样保存到手机的图片会清晰很多。
  • 小程序布局采用rpx单位,UI稿按照750的宽度出图。可直接使用UI稿的尺寸。但是在某些机型上1rpx会无法显示。可以用H5的方式实现1px效果。
  • iphoneX吸底按钮的适配,可以用媒体查询获取wx.getSystemInfo获取机型。参考
JavaScript

@media only screen and (device-width : 375px) and (device-height :
812px) and (-webkit-device-pixel-ratio : 3) { }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e5287c595320097-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5287c595320097-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e5287c595320097-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5287c595320097-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e5287c595320097-1" class="crayon-line">
@media only screen 
</div>
<div id="crayon-5b8f634e5287c595320097-2" class="crayon-line crayon-striped-line">
    and (device-width : 375px) 
</div>
<div id="crayon-5b8f634e5287c595320097-3" class="crayon-line">
    and (device-height : 812px) 
</div>
<div id="crayon-5b8f634e5287c595320097-4" class="crayon-line crayon-striped-line">
    and (-webkit-device-pixel-ratio : 3) { }
</div>
</div></td>
</tr>
</tbody>
</table>
  • 页面A -> 页面B,页面B的操作触发了页面A的数据更新。返回更新页面A的数据,通常有两种方式来实现(我司采用了方案二):
    1. 在页面A监听onShow事件,在onShow事件触发时无脑更新页面数据。
    2. 通过EventBus来实现跨页面通信。
  • 复杂组件的开发,省市区三级联动选择器的开发,获取微信地址库的地址的编码和业务采用的省市区编码对不上。
  • 页面路径的层级,最大不能超过10层。
  • 小程序小程序分包加载,微信对小程序包的大小有如下限制。
  • 整个小程序所有分包大小不超过 8M
  • 单个分包/主包大小不能超过 2M

事件处理

mpvue目前全支持小程序的事件处理器,引入了 Vue.js 的虚拟 DOM ,在前文模版中绑定的事件会被挂在到 vnode 上,同时 compiler 在 wxml 上绑定了小程序的事件,并做了相应的映射,所以在真实点击的时候通过 runtime 中 handleProxy 事件类型分发到 vnode 的事件上,同 Vue 在 WEB 的机制一样,可以做到无损支持。同时还顺便支持了自定义事件和 $emit 机制。

事件映射表,左侧为 WEB 事件,右侧为 小程序 对应事件

图片 8

踩坑注意:

  • 列表中没有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上将bind改为@ @regionchange,同时这个事件也非常特殊,它的 event type 有 begin 和 end 两个,导致我们无法在handleProxy 中区分到底是什么事件,所以你在监听此类事件的时候同时监听事件名和事件类型既 <map @regionchange="functionName" @end="functionName" @begin="functionName">
  • 小程序能力所致,bind 和 catch 事件同时绑定时候,只会触发 bind ,catch 不会被触发,要避免踩坑
  • 事件修饰符 .stop 的使用会阻止冒泡,但是同时绑定了一个非冒泡事件,会导致该元素上的 catchEventName 失效! .prevent 可以直接干掉,因为小程序里没有什么默认事件,比如submit并不会跳转页面 .capture 支持 1.0.9 .self 没有可以判断的标识 .once也不能做,因为小程序没有 removeEventListener, 虽然可以直接在 handleProxy 中处理,但非常的不优雅,违背了原意,暂不考虑
  • 其他 键值修饰符 等在小程序中压根没键盘,所以......

wepy事件绑定区别于vue,根据原生小程序事件提供了语法优化

图片 9

Taro 元素的事件处理和 DOM 元素的很相似。但是有一点语法上的不同:

Taro 事件绑定属性的命名采用驼峰式写法,而不是小写。 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串 (DOM 元素的写法)。

例如,传统的微信****小程序模板:

图片 10

Taro 中稍稍有点不同:

图片 11

在 Taro 中另一个不同是你不能使用 catchEvent 的方式阻止事件冒泡。你必须明确的使用 stopPropagation。例如,阻止事件冒泡你可以这样写:

图片 12

我看小程序

我想从技术的角度来谈谈我对微信小程序的理解,我觉得小程序本身是一个非常优秀的Hybrid App的技术方案。有很多值得学的地方,可以应用到我们Hybrid App的技术方案设计中来。了解和学习小程序技术原理也能更好的优化我们的代码。

小程序开发有哪些痛点?

  • 频繁调用 setData及 setData过程中页面跳闪
  • 组件化支持能力太弱
  • 不能使用 less、scss 等预编译器
  • request 并发次数限制

离线包加载

离线包加载,常见的Hybrid App通过webview加载H5页面,前端页面都是放在服务器端。虽说保证了灵活性。但是加载性能收网速影响大。页面切换白屏时间长。小程序离线包的加载方式。一次性加载所有的前端资源到本地再解压。大大提升了用户体验。不过微信官方为了防止下载离线包的时间过程,也严格限制了小程序包的体积。(分包加载情况下子包大小不能超过2M,也就是初次打开加载的资源不能超过2M)

众所周知如今市面上端的形态多种多样,手机Web、ReactNative、微信小程序, 支付宝小程序, 快应用等,每一端都是巨大的流量入口,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。但面对目前市面上成熟的小程序第三方框架如何针对自己的需求进行选择也是一个麻烦事,本文针对当前市面上的三大转译框架进行一个综合对比,希望能对大家的技术选择有所帮助,如有哪里不妥的地方希望大家指正。

mpvue

由美团团队开发,mpvue和wepy一样也是在小程序上提供了类vue.js的开发体验。作为后来者,抢占了很多wepy的市场份额(ps:我们团队近期也在考虑从wepy迁移到mpvue)。这个框架的原理相比wepy要更加复杂一点,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,提供了更加接近于vue.js的开发体验。

为什么使用第三方框架?

  • 只要熟悉vue或react即可快速上手,学习成本低
  • 一套代码可在多端编译运行(微信,支付宝,h5,RN) 支付宝小程序暂不完善
  • 组件化开发,完美解决组件隔离,组件嵌套,组件通信等问题
  • 支持使用第三方 npm 资源
  • 使小程序可支持 Promise,解决回调烦恼
  • 可使用 Generator Function / Class / Async Function 等特性,提升开发效率
  • 对小程序本身的优化,如生命周期的补充,性能的优化等等
  • 支持样式编译器: Scss/Less,模板编译器,代码编译器:Babel/Typescript。

预加载webview

预加载webview,微信会预加载多一个wkwebview(ios平台)放后台,用户打开小程序时省去初始化wkwebview时间。

1 赞 收藏 评论

图片 13

列表渲染

在列表渲染上三者也分别有不同的应用方法

wepy当需要循环渲染WePY组件时(类似于通过wx:for循环渲染原生的wxml标签),必须使用wepy定义的辅助标签。

图片 14

mpvue使用v-for与vue一致,只是需要注意一点,嵌套列表渲染,必须指定不同的索引!

图片 15

taro的列表循环用法基本与react相同,有一点需要注意,在 React 中,JSX 是会编译成普通的 JS 的执行,每一个 JSX 元素,其实会通过 createElement 函数创建成一个 JavaScript 对象(React Element),因此实际上你可以这样写代码 React 也是完全能渲染的:

图片 16

但是 Taro 中,JSX 会编译成微信小程序模板字符串,因此你不能把 map 函数生成的模板当做一个数组来处理。当你需要这么做时,应该先处理需要循环的数组,再用处理好的数组来调用 map 函数。例如上例应该写成:

图片 17

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:小程序开发实践总结

您可能还会对下面的文章感兴趣: