- 小程序防止重复点击或重复触发事件
可设置全局变量和全局函数,直接使用app唯一实例调用,方便快捷。 在app.js下 App({ globalData: { PageActive: true }, preventActive (fn) { const self = this if (this.globalData.PageActive) { this.globalData.PageActive = false if (fn) fn() setTimeout(() => { self.globalData.PageActive = true }, 1500); //设置该时间内重复触发只执行第一次,单位ms,按实际设置 } else { console.log('重复点击或触发') } } }) 其他page下调用 index.wxml <button bindtap="tap">点击</button> index.js Page({ tap (e) { getApp().preventActive(()=>{ //code... }) } })
2021-01-12 - 怎样识别字符串中的手机号,手机号高亮显示,并且可以点击这个手机号,拨打电话?
我们的需求是这样的》 客户留了一段备注信息,里面可能会有手机号(可能是多个号码),怎么才能识别出手机号,并且手机号要能高亮显示,当用户看到手机号的时候,直接点击手机号就可以拨打电话了,这样的功能App里面很好实现,但是小程序怎么实现呢。
2019-11-04 - 【技巧】swiper仿tab切换
大家好,上次给大家分享了swiper多图片的解决方案:https://developers.weixin.qq.com/community/develop/doc/000068ff25ccf0bae4e76eab156c04 今天再给大家分享一个关于swiper的小技巧,利用swiper仿tab切换。 相信大家在app或浏览器上阅读新闻时,比如今日头条,会有这样一个场景,左右滑动的时候可以切换不同栏目,体验非常好,但是小程序好像没有提供相关组件,如果想实现这种效果该怎么做呢今天就给大家介绍一下在小程序里是怎么实现的。 首先先看下效果 [图片] 实现原理很简单,利用小程序swiper再配合scroll-view就能实现,不过这里面有几点需要注意一下: 1.scroll-view一定要给一个高度,不然会有问题; 2.切换的时候只显示当前的swiper-item里的内容,其它swiper-item里的内容可以先隐藏掉,这是因为如果你的swiper-item里的图片太多的话可能会造成页面回收,因为新闻列表大多是图文列表,而tab经常是不止两个的,可能是7、8个或更多,如果每个tab都显示的话到时上拉加载页面会非常庞大,所以这里我建议不用显示的内容先隐藏,记住是swiper-item里的内容不是swiper-item,到时切换回来时再重新渲染,如果你要保存滚动的位置还要做其它的一些处理,这里就不仔细讲解了; 3.这里适用的是整个页面都是tab切换的,如果只是在页面的某处实现tab切换,还要考虑高度的问题,加载数据的时候根据数据个数长度来计算高度,每次加载数据都要计算高度,切换到不同的tab也是,这部分比较麻烦,因为要计算,不过并不难,只要 计算正确的话是没有问题的; 大概就是这样,基本实现思路,大家可以根据这个思路去拓展,在上面加上自己的功能,over! 代码片段:https://developers.weixin.qq.com/s/89OO1smX736d 系甘先,得闲饮茶
2019-02-26 - 【转】微信小程序中实现瀑布流布局和无限加载
瀑布流布局是一种比较流行的页面布局方式,最典型的就是Pinterest.com,每个卡片的高度不都一样,形成一种参差不齐的美感。 在HTML5中,我们可以找到很多基于jQuery之类实现的瀑布流布局插件,轻松做出这样的布局形式。在微信小程序中,我们也可以做出这样的效果,不过由于小程序框架的一些特性,在实现思路上还是有一些差别的。 今天我们就来看一下如何在小程序中去实现这种瀑布流布局: [图片] 小程序瀑布流布局 我们要实现的是一个固定2列的布局,然后将图片数据动态加载进这两列中(而加载进来的图片,会根据图片实际的尺寸,来决定到底是放在左列还是右列中)。 [代码]/* 单个图片容器的样式 */.img_item { width: 48%; margin: 1%; display: inline-block; vertical-align: top; }[代码]我们知道,在HTML中,我们要动态加载图片的话,通常会使用new Image()创建一个图片对象,然后通过它来动态加载一个url指向的图片,并获取图片的实际尺寸等信息。而在小程序框架中,并没有提供相应的JS对象来处理图片加载。其实我们可以借助wxml中的[图片]组件来完成这样的功能,虽然有点绕,但还是能满足我们的功能要求的。 [代码]<view style="display:none"> <image wx:for="{{images}}" wx:key="id" id="{{item.id}}" src="{{item.pic}}" bindload="onImageLoad">image>view>[代码]我们可以在Page中通过数据绑定,来传递要加载的图片信息到wxml中,让[图片]组件去加载图片资源,然后当图片加载完成的时候,通过bindload指定的事件处理函数来做进一步处理。 我们来看一下Page文件中定义的onImageLoad函数。在其中,我们可以从传入的事件对象e上,获取到[图片]组件的丰富信息,包括通过它加载进来的图片的实际大小。然后我们将图片按照页面上实际需要显示的尺寸,计算出同比例缩放后的尺寸。接着,我们可以根据左右两列目前累积的内容高度,来决定把当前加载进来的图片放到哪一边。 [代码]let col1H = 0;let col2H = 0; Page({ data: { scrollH: 0, imgWidth: 0, loadingCount: 0, images: [], col1: [], col2: [] }, onLoad: function () { wx.getSystemInfo({ success: (res) => { let ww = res.windowWidth; let wh = res.windowHeight; let imgWidth = ww * 0.48; let scrollH = wh; this.setData({ scrollH: scrollH, imgWidth: imgWidth }); //加载首组图片 this.loadImages(); } }) }, onImageLoad: function (e) { let imageId = e.currentTarget.id; let oImgW = e.detail.width; //图片原始宽度 let oImgH = e.detail.height; //图片原始高度 let imgWidth = this.data.imgWidth; //图片设置的宽度 let scale = imgWidth / oImgW; //比例计算 let imgHeight = oImgH * scale; //自适应高度 let images = this.data.images; let imageObj = null; for (let i = 0; i < images.length; i++) { let img = images[i]; if (img.id === imageId) { imageObj = img; break; } } imageObj.height = imgHeight; let loadingCount = this.data.loadingCount - 1; let col1 = this.data.col1; let col2 = this.data.col2; //判断当前图片添加到左列还是右列 if (col1H <= col2H) { col1H += imgHeight; col1.push(imageObj); } else { col2H += imgHeight; col2.push(imageObj); } let data = { loadingCount: loadingCount, col1: col1, col2: col2 }; //当前这组图片已加载完毕,则清空图片临时加载区域的内容 if (!loadingCount) { data.images = []; } this.setData(data); }, loadImages: function () { let images = [ { pic: "../../images/1.png", height: 0 }, { pic: "../../images/2.png", height: 0 }, { pic: "../../images/3.png", height: 0 }, { pic: "../../images/4.png", height: 0 }, { pic: "../../images/5.png", height: 0 }, { pic: "../../images/6.png", height: 0 }, { pic: "../../images/7.png", height: 0 }, { pic: "../../images/8.png", height: 0 }, { pic: "../../images/9.png", height: 0 }, { pic: "../../images/10.png", height: 0 }, { pic: "../../images/11.png", height: 0 }, { pic: "../../images/12.png", height: 0 }, { pic: "../../images/13.png", height: 0 }, { pic: "../../images/14.png", height: 0 } ]; let baseId = "img-" + (+new Date()); for (let i = 0; i < images.length; i++) { images[i].id = baseId + "-" + i; } this.setData({ loadingCount: images.length, images: images }); } })[代码]这里是显示在两列图片的wxml代码,我们可以看到在scroll-view>组件上,我们通过使用bindscrolltolower设置了事件监听函数,当滚动到底部的时候,会触发loadImages去再加载下一组的图片数据,这样就形成了无限的加载:/scroll-view> [代码]<scroll-view scroll-y="true" style="height:{{scrollH}}px" bindscrolltolower="loadImages"> <view style="width:100%"> <view class="img_item"> <view wx:for="{{col1}}" wx:key="id"> <image src="{{item.pic}}" style="width:100%;height:{{item.height}}px">image> view> view> <view class="img_item"> <view wx:for="{{col2}}" wx:key="id"> <image src="{{item.pic}}" style="width:100%;height:{{item.height}}px">image> view> view> view>scroll-view>[代码]好了,挺简单的一个例子,如果你有更好的方法,不吝分享一下哦。 完整代码可以在我的Github下载:https://github.com/zarknight/wx-falls-layout 原作者:一斤代码(简书作者) 原文链接:http://www.jianshu.com/p/260f2623562d
2016-11-29 - 每日出击运签小程序“踩坑”总结
最近刚好接手支持了每日出击运签的小程序,在小程序完成以后,整理了一下初次接手小程序的一些体验,所以有了现在这篇小总结。在小程序需求的进行期间,十分感谢泽贤,小苏,俞焕,花花的指导~ 话不多说,立马送上小程序码,大家可以扫码体验一下 [图片] 每日出击运签小程序主要划分为几个功能模块: 摇一摇 抽签并显示运签结果 保存图片 预约功能 签到功能 积分功能 评论功能 下面重点介绍一下摇一摇、抽签并显示运签结果、保存图片三个功能。 关于摇一摇功能 花叔早前已经写过文章(链接如下:http://www.ifanr.com/minapp/880378)介绍过摇一摇的实现思路了,这里简单归纳一下摇一摇功能的几个主要的思路。 准备: 需要设置一组变量,保存摇一摇x,y,z三轴的数值,需要设置一个变量来记录摇一摇的时间。 实现注意事项: 我们需要定一个阈值,作为摇一摇的判断基准。 需要通过公式来计算单位时间内运动的路程,也就是我们想要的速度。如果这个速度超过了我们定下来的阈值,那么就算作用户已经摇一摇 [代码]//计算 公式的意思是 单位时间内运动的路程,即为我们想要的速度[代码][代码]var[代码] [代码]speed = Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime * 10000;[代码] 另外我们需要注意两个小程序提供的API: wx.onAccelerometerChange(CALLBACK):用于监听加速度数据,在发生有加速度的动作的时候,执行摇一摇的判断逻辑 wx.stopAccelerometer:在摇一摇的逻辑执行期间,需要停止监听加速度数据,避免多次触发摇一摇 为了给予用户更好的摇一摇反馈,建议在执行摇一摇以后设置振动反馈,这个小程序API里面也带有相关的接口:wx.vibrateShort(OBJECT) 关于抽签并显示运签结果的功能 每日出击运签的小程序其中有一个需求是抽签并显示运签结果。在用户每天进入小程序的时候,通过摇一摇,得到一个抽签结果,如图所示: [图片] 关于这块功能,这里需要着重介绍vine在实现小程序的过程中比较关注的两个点,一个是随机显示抽签结果,一个是用于显示签纸的动画效果。 随机显示抽签结果 这个小程序中,随机显示抽签结果的需求具体如下: 随机出现五个运签结果,大吉、吉、平、凶、大凶;不同结果对应下面不同文案;每个用户每天只能获取同一个结果。随机文案,每个用户在用完库存前不重复 这里我们可以提炼出两个关键点:一个是每个用户每天获取的结果不变,一个是,在库存用完前不重复出现文案 也就是说,我们需要把用户的抽签结果和用户id关联起来。另外我们需要准备储存抽签结果的数组,每天从数组里面取出一个值作为抽签结果,从而保证在库存用完前不重复出现文案。贴代码: [代码]// 打乱数组顺序[代码][代码] [代码][代码]function[代码] [代码]shuffle(a) {[代码][代码] [代码][代码]var[代码] [代码]j, x, i;[代码][代码] [代码][代码]for[代码] [代码](i = a.length - 1; i > 0; i--) {[代码][代码] [代码][代码]j = Math.floor(random() * (i + 1));[代码][代码] [代码][代码]x = a[i];[代码][代码] [代码][代码]a[i] = a[j];[代码][代码] [代码][代码]a[j] = x;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]var[代码] [代码]m_w = 123456789;[代码][代码] [代码][代码]var[代码] [代码]m_z = 987654321;[代码][代码] [代码][代码]var[代码] [代码]mask = 0xffffffff;[代码] [代码] [代码][代码]function[代码] [代码]seed(i) {[代码][代码] [代码][代码]m_w = i;[代码][代码] [代码][代码]m_z = 987654321;[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]function[代码] [代码]random() {[代码][代码] [代码][代码]m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;[代码][代码] [代码][代码]m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;[代码][代码] [代码][代码]var[代码] [代码]result = ((m_z << 16) + m_w) & mask;[代码][代码] [代码][代码]result /= 4294967296;[代码][代码] [代码][代码]return[代码] [代码]result + 0.5;[代码][代码] [代码][代码]}[代码] [代码]//获取用户id [代码][代码] [代码][代码]var[代码] [代码]userid = parseInt(gbConfig.user_id, 16);[代码][代码] [代码][代码]seed(userid);[代码][代码] [代码][代码]// 随机生成抽签描述[代码][代码] [代码][代码]var[代码] [代码]qian = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];[代码][代码] [代码][代码]var[代码] [代码]result = [];[代码][代码] [代码][代码]for[代码] [代码]([代码][代码]var[代码] [代码]i = 0; i < 10; i++) {[代码][代码] [代码][代码]shuffle(qian);[代码][代码] [代码][代码]result = result.concat(qian);[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]// 随机生成抽签结果[代码][代码] [代码][代码]var[代码] [代码]luck = [1, 2, 3, 4, 5];[代码][代码] [代码][代码]var[代码] [代码]luckarr = [];[代码][代码] [代码][代码]for[代码] [代码]([代码][代码]var[代码] [代码]i = 0; i < 60; i++) {[代码][代码] [代码][代码]shuffle(luck);[代码][代码] [代码][代码]luckarr = luckarr.concat(luck);[代码][代码] [代码][代码]}[代码] 2.签纸显示的动画效果 这次小程序,在上线前添加了签纸显示的动画效果,以加强“抽签”的用户感受。签纸以滚轴的形式向下展开,慢慢呈现出签纸的结果。 关于动画效果,最容易被使用的实现方式应该就是css3动画以及序列帧。这里尝试了三套方案,最终选择了最后一套。下面分别来介绍一下这三套方案。 第一:使用传统的序列帧方式。尝试使用传统的序列帧,通过逐帧动画,慢慢铺开签纸,逐帧动画如下: [图片] 在通过减帧以后,得到了8张序列帧图,vine发现,8张序列帧图通过拼接得到的雪碧图会非常大(达到了1M左右的大小),所以再次进行减帧得到由4张序列帧图拼接而成的雪碧图(也有500+kb左右)。但是在实际放到页面上面的时候发现,4张序列帧图帧数太少,造成了动画卡顿不流畅的情况,而且在低端安卓机上面,这组序列帧动画完全无法流畅进行。所以第一套方案放弃。 第二:把8张序列帧图分开加载,4张为一组,拼接成一张雪碧图,一共两张雪碧图,如下: [图片] [图片] vine的处理方式是:先加载第一张雪碧图,在第一张雪碧图逐帧动画结束后,切换到第二张雪碧图,无缝连接播放第二组逐帧动画。结果在低端安卓机上面出现了同样的情况,动画播放非常卡顿,而且在图片切换的过程中出现了空白。于是第二套方案失败。 第三:在vine百思不得其解的时候,突然发现,这套序列帧有一个特点:它的签纸和卷轴并不是立体的!也就是说,这里其实可以不需要序列帧来实现签纸打开的效果,只需要最后一张图就可以了: [图片] 关于保存图片的功能 保存图片的功能是这次小程序中的一个大难点,这里非常感谢泽贤和小苏提供的建议。下面来介绍一下保存图片的功能到底是什么: [图片][图片] 通过点击分享按钮,可以生成一张和签纸类似的图片,用户可以长按保存这张图片到手机本地。从而达到转发分享的目的。 而这个保存,所需要的就是canvas。小程序API提供了canvas的接口: [图片] 通过这个接口,我们可以把当前画布指定区域的内容导出成指定大小的图片,然后再调用小程序的预览接口进行图片预览以及保存: [图片] 但是在这里,vine遇到了几个问题: 多次点击保存按钮触发canvas,导致手机滑动的时候非常卡顿 生成预览图片时间非常慢 三星note5保存图片尺寸的问题 下面来介绍一下这两个问题相应的解决措施: 多次点击保存按钮触发canvas,导致手机滑动的时候非常卡顿 canvas只在需要触发的时候渲染,在用户没有点击保存按钮的时候,默认不渲染canvas。代码如下:由于小程序和MVVM框架类似,无法直接操作dom,所以vine采取了在样式上面添加状态,通过修改showcanvas变量的值,来控制canvas的显示和隐藏。在执行画图操作的时候使变量值为false,显示canvas,在绘制完成的时候更改变量值,隐藏canvas [代码]<[代码][代码]canvas[代码] [代码]class[代码][代码]=[代码][代码]'{{showcanvas ? "hidcanvas" : "showcanvas"}}'[代码] [代码]style[代码][代码]=[代码][代码]"width: 750px; height: 1334px;position:fixed;left:100000rpx;top:-100000rpx;"[代码] [代码]canvas-id[代码][代码]=[代码][代码]"shareQRcode"[代码][代码]></[代码][代码]canvas[代码][代码]>[代码] 生成预览图片时间非常慢 生成预览图片时间非常慢,目前判断的原因是,直接预览canvas临时路径的图片耗时比较久。那么应该如何优化这个过程呢? 小程序的API提供了几个关于文件的接口: [图片] [图片] [图片] 我们可以通过这几个接口优化目前的预览方式。在这其中vine做了两种不同的尝试。 第一,在执行wx.previewImage的success的回调的时候,把previewImage生成的临时路径保存下来,下次再点击预览的时候,直接获取本地已保存的文件列表wx.getSavedFileList,取得最近保存下来的文件的本地路径,进行预览。这么做的想法主要是为了解决canvas渲染的问题,每天只渲染一次,后续都是通过预览本地图片链接达到生成图片的目的。梳理一下流程: 初次渲染:canvasToTempFilePath -> previewImage -> saveFile 二次渲染:getSavedFileList -> previewImage 可惜理想始终是丰满的,在实际操作的过程中vine发现,通过这样的方式预览图片的时候,一直处于loading的状态,无法生成初次渲染的图片。vine非常苦恼,至今没能找到原因。 于是vine想了另一种办法,调整了预览的顺序如下: 初次渲染:canvasToTempFilePath -> saveFile -> previewImage 二次渲染:getSavedFileList -> previewImage 这时候vine发现,先把canvas生成的临时路径保存到本地,再预览,这种方法是可行的!而且在二次渲染的过程中,由于只是读取小程序本地的图片路径,无需再次调用canvas绘图,二次预览的时间大大减少。 在这里我们需要注意官方文档中提到的一点:小程序本地文件存储的大小限制为10M。所以我们需要调用wx.removeSavedFiled的方法删除我们不需要的图片(当天之前存下来的图片都是我们无需保存到本地的图片,可以删除) 三星note5保存图片尺寸的问题 在数量庞大版本不一的安卓手机上,vine收到反馈,三星note5在保存图片的时候会遇到图片底部被裁减的情况。在通过多次修改以及对比类似的小程序以后发现,note5用canvas绘制的图片有一个最大的范围是750*1150,超出这个范围的图片,底部就会被裁减。为什么会有这个最大范围vine目前还没探索出结论,希望遇到过这个问题的大神可以和vine交流一下心得,手动比心!~ 最后梳理一下小程序项目的一些注意点: 小程序需要申请小程序公司主体的账号,拿到appid,给到后台同学配置接口 小程序的体验需要上传体验版本,获取体验者的微信号,到小程序管理后台开通体验者权限 小程序开发过程中需要的单位为rpx,兼容问题较少 在小程序的需求中,需要仔细查看文档中提到的版本以及兼容问题,做好降级处理:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/compatibility.html
2018-01-29 - iOS 开发者的微信小程序初体验
0.序言 当前端在谈论微信小程序的时候,iOS 开发在谈论什么。 本职是iOS 移动开发的,最近研究了一下比较火的微信小程序。前端0基础,研究也不是很透彻,所以大家一定要保持怀疑的态度看这一篇分享。由于是本职是iOS开发所以在开发小程序的时候也会按照之前iOS开发的一点点经验来搭建小程序。所以主要是从几个应用框架层来比较说明一下iOS 和 微信小程序之间的异同点。理论基础来自官方文档再加上自己一点点实践(从图可以看出这渲染跟原生App很相像了) [图片] 1.网络层 网络层:这是必要的基础建设。 [图片] 小程序:上图是小程序的后台服务器配置,必须要事先配置好服务器,否则在程序中是无法正常请求的。一个小程序同时只能有一个 WebSocket连接,并且同时也只能有5个网络请求连接。请求的服务器地址必须是HTTPS协议的,看了后台服务器地址配置,上传和下载文件的服务器也是单独设置。很重要的一点也令人头疼的是小程序是不支持H5页面跳转也是不支持cookie。 iOS :苹果规定从2017年1月起App内的网络链接强制使用HTTPS协议的,iOS 可以设置网络请求数的。通过参数maxConcurrentOperationCount 来设置请求数,但是也不是任意设置的,在2G网络一次只能维持1个链接,3G是2个,在WiFi和4G网络环境下是不限链接数的,这里说明下并不是并发链接数越多越好,越多占用带宽越高,请求时间反而会延迟。 所以这里对小程序同时有5个网络请求有点疑惑,是否不区分网络? 这里数据回调处理比较类似。(小程序有点类似block) [代码]// 网络请求[代码][代码] [代码][代码]wx.request({[代码][代码] [代码][代码]url: [代码][代码]'https://aq.qq.com'[代码][代码],[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]x: [代码][代码]''[代码] [代码],[代码][代码] [代码][代码]y: [代码][代码]''[代码][代码] [代码][代码]},[代码][代码] [代码][代码]header: {[代码][代码] [代码][代码]'Content-Type'[代码][代码]: [代码][代码]'application/json'[代码][代码] [代码][代码]},[代码][代码] [代码][代码]success: [代码][代码]function[代码][代码](res) {[代码][代码] [代码][代码]console.log(res.data)[代码][代码] [代码][代码]}[代码][代码]})[代码] 2.本地持久化存储/数据层 小程序:为每一个小程序提供了10M的缓存,用来存储数据和文件,现在是内测阶段,不知道以后会不会扩容。 数据:看官方的API目前只支持”key-data”的简单键值存储以及set/get/remove/clear数据操作,还不支持数据库。 文件:在文件存储方面,小程序是默认都是临时路径,本次程序运行期间可以正常读取,退出程序后就删除。所以如果要持久存储,需要再调用wx.saveFile放到本地存储,下次打开程序还能正常访问到。 iOS:为每一个App创建一个沙盒,沙河有3个文件夹Document/Library/tmp,根据这个文件夹的命名大概就可以猜出它们不同用途。iOS 这边存储方案就种类繁多,品种丰富。Core Data、SQLite、NSUserDefaul、keychain、plist、archive根据自己的需求选取数据存储方案。这里只是简单说明一下iOS 持久化存储,其实它是非常庞大的一个点,iOS是一个小型的操作系统,存储和文件操作是有一套完整的方案。 3.业务层/UI层 在小程序中一个完整的页面page是由.js/.json/.wxml/.wxss这四个文件组成,每个界面.js .wxml是必选项其它两项选填。iOS并没有这样的强制规定,一个界面可以完全在一个`UIViewController`里面完成,复杂的页面iOS也是可以通过类似的文件拆分使得结构更加清晰明了。 .js:页面逻辑 iOS中一个完整界面可以只有一个UIViewController,在UIViewController中实现了页面的大部分逻辑代码,在可读性可以规范一下页面的代码布局,属性初始化,生命周期函数,回调函数,事件处理,自定义方法等。代码结构布局大概是这样子,但是也不一定所有的UIViewController都要有。同样小程序中也有同样结构数据,生命周期,控件绑定事件,自定义方法。这样可以提高代码的可维护性和可读性。毕竟小程序还没有 control + 6这样的快捷键。 [图片] 看到上面对比,发现两者还是很相似的,这样对比看还是有助我们了解小程序。简单对比一下生命周期函数。 [图片] .json 公共配置 在.json文件中可以配置导航栏的样式,tarBar的配置,刷新控件,网络超时时间等。一个小程序只有一个总的app.json公共配置,其它的page也有.json文件但是只能配置导航栏的样式,其它都继承app.json里面的公共配置。很重要的一点就是你创建所有的.js的文件都需要添加到app.json中。不添加编译器也不会报错,但是你会发现跳转到某个页面一直不成功一直显示不出来,这个时候就要检查一下有没有在app.json中添加改文件了。 .wxml 页面结构.wxss 页面组件样式 这个.wxml可以想象成在UIViewController里面放一些控件,比如这个页面有多少图片,按钮,已经控件之间的层级关系,绑定事件等。但是呢,在.wxml里面不能设置图片的大小,圆角,位置。这时候.wsxx的作用就体现出来了,.wxss主要是用来描述.wxml组件的样式。 举个例子:在App 中应用广泛的UITableView在小程序中是怎么实现的 [图片][图片] 小程序提供了很多UI组件,基本可以满足大部分界面需求。这些组件基本都能在iOS中找到相对应的。在小程序中这些组件是有一些共同属性,同时每个组件又有自己一些独有的属性。跟在iOS 中很多UI控件都继承同一个大类UIView是一样的道理的。 [图片] 4.动画canvas:画布。这是要单独拿出来讲,动画这个东西呢,真是一言难尽,水太深,有点淌不动。iOS 动画框架Core Animation 功能也是很庞大,有兴趣可以看《iOS Core Animation: Advanced Techniques》 5.消息通知 小程序消息通知并没有实践实现过,只能是看着文档来瞎猜了。先看下iOS客户端关于push消息通知的实现。 [图片] [图片] iOS :主要是devToken,Provider,APNs这三者之间的交互。App向注册通知之后系统会返回一个devToken,然后将这个devToken上传服务器Provider。Provider将要发送给用户的消息和devToken发送给APNs,最后由APNs向用户设备发送通知消息(iOS 10 新增了Notification Extension的扩展,使得Local Notification和Remote Notification都变得非常丰富。) 小程序:小程序这边并不能像App那样发送通知,但是提供了另一种通知方式-模板消息。这边使用AppID 和 AppSecret 注册获取access_token。这个access_token是通过中控服务器来获取和刷新。所以我想把access_token看作devToken,中控服务器就是Provider,微信下发模板消息的服务器就是APNs。 [图片] 小结:devToken是客户端获取上传到Provider服务器,这边access_token是中控服务器来维护。还有小程序中模板消息的发起方还是要求证一下,跟微信服务器交互的是中控服务器还是小程序本身?具体模板消息参数设置官方文档。 6.支付 第三方支付接入客户端都没有接触过。但是在微信小程序里面直接呼起微信支付应该比较简单,小程序也提供了接口,去看官方API吧。 7.开发工具 开发工具调试页面中wxml类似于Reveal界面调试工具,可以动态查看和修改应用程序的界面,对于我这种新手学习和调试CSS各控件的样式觉得非常的方便。开发工具还在不断更新,补充一些新的功能,更新API,要是看到API跟本文有所不同请以官方API文档为准,写这篇文章的时候官方又有新的更新....我需要一个全局搜索功能。 8.总结 小程序是个小而美的东西,某些方面可以渲染的跟native一样,也提供了消息通知和本地存储的能力,完全可以替代一些对native要求不是很高的App。但从微信限定的10M内存,页面层级不能超过5层来说,小程序也不适合太过深度的用户体验。
2016-11-07