微信小程序开发实战(笔记)

本文由清尘发表于2017-09-11 15:38最后修改于2017-10-10属于LIFE分类

小程序,巧应用:微信小程序开发实战(第2版)
熊普江 谢宇华

◆ 2.1 理解小程序

>> 目录结构显示:小程序项目在创建时的目录(示例的本地开发目录为:“D:\小程序巧应用”)之下,包含3个app开头的文件(app.js、app.json、app.wxss)以及pages目录与utils目录。其中pages目录存放2个页面(index与logs)的构成文件。从示例中,我们看到:每个页面都是一个目录,目录名就是唯一的页面名,其下再由以页面名为前缀的2~4个文件组成。对小程序的目录文件结构,我们可以归纳一下,如图2-3所示。[插图]图2-3 小程序的目录文件结构左侧3个app文件必须放在小程序根目录下,其他文件则由开发者自由控制。这3个文件说明如下:■app.js是小程序的脚本代码,用来监听并处理小程序的生命周期函数、声明全局变量。■app.json是对整个小程序的全局配置,配置小程序是由哪些页面组成,配置小程序的窗口背景色等。■app.wxss是整个小程序的公共样式表。其中app.js和app.json是必需的。小程序页面是由同路径下同名但不同后缀的2~4个文件组成:■.js后缀的文件是页面脚本文件,该文件实现页面逻辑与事件处理。■.json后缀的文件是页面配置文件。■.wxss后缀的是页面样式表文件。■.wxml后缀的文件是页面结构文件,该文件与.wxss文件一起构建出页面。其中.js与.wxml文件是必需的。

>> 微信小程序中的每一个页面的“路径+页面名”都需要写在app.json的pages中,且pages中的第一个页面是小程序的首页。

>> index.json是页面的配置文件。页面的配置文件同样是非必要的,而且只能配置window配置项的属性值。当页面有配置文件时,文件中的配置项在该页面上会覆盖app.json的window中相同的配置项。若没有指定页面的配置文件,则在该页面直接使用app. json中的默认配置项

>> 上述代码中的block并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性(如wx:for或wx:if)

>> 理解小程序的线程架构后,我们基本上可以归纳出一个小程序开发的主要步骤,涉及两大步骤:1)创建小程序实例(定义、配置及页面执行关联)。即编写3个app前缀的文件,它们共同描述了整个小程序主体逻辑、生命周期及页面构成、样式等。小程序实例将由appServer线程执行。2)创建页面(编写页面结构与事务处理逻辑)。在小程序中一个完整的页面(page)是由.js、.json、.wxml、.wxss这四个文件组成,每个界面.js和.wxml是必选项,其他两项是可选项。小程序页面中的.wxss与.wxml文件由view线程执行,.js文件由appServer线程执行。我们利用组件编写界面(UI)代码,以展现页面数据或内容视图,这部分代码就保存为页面的wxml文件:■微信小程序中的每一个页面的“路径+页面名”都需要写在app.json文件里名为pages的配置项中,且pages配置项中的第一个页面是小程序的首页。■.wxml文件与.wxss文件是小程序开发框架的一部分

>> 通过框架图我们可以看到两大部分:在页面视图层,wxml是MINA提供的一套类似于HTML标签的语言以及一系列基础组件。开发者使用wxml文件来搭建页面的基本视图结构,使用wxss文件来控制页面的展现样式。AppService应用逻辑层是MINA的服务中心,由微信客户端启用异步线程单独加载运行。页面渲染所需的数据、页面交互处理逻辑都在AppService中实现。MINA框架中的AppService使用JavaScript来编写交互逻辑、网络请求、数据处理,但不能使用JavaScript中的DOM操作。小程序中的各个页面可以通过AppService实现数据管理、网络通信、应用生命周期管理和页面路由。MINA框架为页面组件提供了bindtap、bindtouchstart等事件监听相关的属性,来与AppService中的事件处理函数绑定在一起,实现页面向AppService层同步用户交互数据。MINA框架同时提供了很多方法将AppService中的数据与页面进行单向绑定,当AppService中的数据变更时,会主动触发对应页面组件的重新渲染。MINA使用Virtual-DOM技术,加快了页面的渲染效率。框架的核心是一个响应的数据绑定系统,它让数据与视图非常简单地保持同步。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新

>> 我们开发者编写的所有代码最终将会打包成一份JavaScript,并在小程序启动的时候运行,直到小程序销毁。这类似ServiceWorker或webpack,所以逻辑层也称之为App Service。

>> 1.页面临时数据或缓存在Page()中,我们要使用setData函数来将数据从逻辑层发送到视图层,同时改变对应的this.data的值。

>> 2.文件存储(本地存储)使用数据API接口,如下所示:■wx.getStorage:获取本地数据缓存。■wx.setStorage:设置本地数据缓存。■wx.clearStorage:清理本地数据缓存。3.网络存储或调用上传或下载文件API接口,如下:■wx.request:发起网络请求。■wx.uploadFile:上传文件。■wx.downloadFile:下载文件。调用URL的API接口,如下:■wx.navigateTo:新窗口打开页面。■wx.redirectTo:原窗口打开页面。

>> 小程序在用户的微信中启动,相当于开启一个WebView,这与HTML5不一样,在一定的时间内除非手动关闭,即使返回打开另一个小程序,原来的小程序也一直以后台的形式运行在内存里,即在后台运行。

>> 与浏览器BOM(Browser Object Model,浏览器对象模型)相关的API都没有。由于小程序框架并非运行在浏览器中,所以JavaScript在Web中的一些能力都将无法使用,比如document、window等,但在这些BOM中,对开发影响最大的应该是没有cookie。

>> 小程序中是没有cookie的,为了兼容目前大部分Web App的登录管理时使用cookie的,小程序在请求发送时,客户端可以动态地给请求设置Header发送报文的cookie。

>> 小程序开发相比HTML5的改进优化登录方面:HTML 5中,通过微信授权一般采用URL重定向的方式获取代码;在小程序中,通过wx.login获取代码,这样避免了之前登录重定向的问题。存储方面:小程序用storage替代了HTML 5中的localstorage、sessionstorage。storage对每个小程序的大小是5M,支持同步和异步。微信支付路径不再受限。

>> 小程序开发相比HTML5开发不方便的地方不方便的地方有明显两点:■每个页面需要手动在app.json中进行注册。如果没有注册,是不执行该页面的。■打开的页面有5个限制,在开发时需要注意控制打开页面的数量。

◆ 3.1 配置

>> 微信小程序的全局配置保存在app.json文件中。开发者通过使用app.json来配置页面文件(pages)的路径、窗口(window)表现、设定网络超时时间值(networkTimeout)以及配置多个切换页(tarBar)等。

>> 1.pages配置项pages配置项接受一个数组,用来指定小程序由哪些页面组成,是必需的配置项。数组的每一项都是字符串,代表对应页面的“路径+文件名”信息。pages配置项要注意三点:1)数组的第一项用于设定小程序的初始页面,即小程序启动页。2)小程序中新增/减少页面,都需要对pages数组进行修改。3)文件名不需要写文件后缀。小程序框架会自动去寻找路径.json、.js、.wxml、.wxss这四类文件进行整合。

>> 2.window配置项window配置项接受对象值,用来设置小程序的状态栏、导航条、标题、窗口等对象的颜色、背景色、内容属性,非必填配置项。没有配置时将使用默认值。

>> 3.tabBar配置项小程序可以是多标签页切换的应用,这种情况下,就需要通过tabBar配置项来指定标签页的表现,及标签页切换时所显示的对应页面

>> list(列表)接受数组值,数组中的每一项也都是一个对象。

>> 除了全局的app.json配置外,还可以.json文件对小程序项目中的每一个页面进行配置,但只能设置本页面的窗口表现。也就是说,页面.json文件配置比app.json配置简单得多,只能设置window配置项的内容。显然页面.json文件中的window配置值将覆盖app.json中的配置值。页面.json文件只能设置window配置项,以决定本页面的窗口表现,所以配置中也无需写window这个键值

>> 前台、后台:用户当前界面运行或操作小程序时为前台;当用户点击左上角关闭,或者按了设备Home键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。销毁:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正销毁。此时代表小程序的生命周期结束

>> 微信团队为开发者提供了全局的getApp()函数,可以用来获取小程序实例。

>> ■App()方法须在app.js中注册,且不能注册多个。■不要在定义App()内的函数中调用getApp(),使用this就可以拿到App实例。■通过getApp()获取实例之后,不要私自调用生命周期函数(如onLaunch、onShow、onHide等)。

>> 在逻辑层,Page()方法用来注册一个页面。Page()接受一个object参数,用于指定页面的初始数据、生命周期函数、事件处理函数等。Page()方法,每个页面有且仅有一个,存在于该页面的.js文件中

>> 微信团队为开发者提供了getCurrentPage()函数,用来获取当前页面的实例。

>> 不要在App()中进行onLaunch操作的时候调用getCurrentPage(),此时page还没有生成。

>> onLoad是页面加载时执行的初始化操作:■一个页面只会调用一次。■参数可以获取wx.navigateTo和wx.redirectTo及navigator中的query。

>> onShow是页面显示时执行的操作。每次打开页面都会调用一次。onReady是页面初次渲染完成时执行的操作:■一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。■对页面的设置(如wx.setNavigationBarTitle)请在onReady之后设置。

>> 3.页面相关事件处理函数onPullDownRefresh是下拉刷新时执行的操作,例如:■监听用户下拉刷新事件。■需要在页面.json文件的window配置项中开启enablePullDownRefresh。■当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。onShareAppMessage是用户分享时返回定制的分享内容:■只有定义了此事件处理函数,右上角菜单才会显示“分享”按钮。■用户点击分享按钮的时候会调用。■此事件需要return一个Object,用于自定义分享内容。

>> getCurrentPages()函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面

>> 1.文件作用域在页面的JavaScript(.js)脚本文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。通过全局函数getApp()可以获取全局的应用实例,如果需要全局的数据可以在App()中设置

>> 模块只有通过module.exports才能对外暴露接口以供其他.js文件引入使用。

>> WXML具有数据绑定、列表渲染、条件渲染、模板及事件绑定的能力

>> 一般来说,wx:if有更高的切换消耗,而hidden有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用hidden更好;如果运行时条件不大可能改变,则wx:if较好。

>> import的作用域import有作用域的概念,即只会引用目标文件中定义的template,而不会引用目标文件嵌套import的template

>> includeinclude可将目标文件除模板代码(template)块的所有代码引入,相当于拷贝到include位置

>> bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡

>> 本地资源无法通过WXSS获取,所以WXSS中的样式都是用的网络图片,或者base64

>> 1.尺寸单位WXSS新增了针对移动端屏幕的两种尺寸单位:rpx与rem。rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。[插图]rem(root em):规定屏幕宽度为20rem;1rem =(750/20)rpx。

>> 定义在app.wxss中的样式为全局样式,作用于每一个页面。在page的.wxss文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖app.wxss中相同的选择器。

>> (2)适配WXSS刚开始时并不能适配各种设备,虽然支持rem,但是并不能改变HTML的属性,这使得HTML 5中的rem适配方案失效。最终微信团队推出了rpx(responsive pixel)这个新的计量单位,它规定屏幕宽度为750rpx,从而可以依据屏幕宽度进行自适应。rpx的实现原理跟rem很相似,而且最终也是换算成rem。rpx计量最大的优势在于750设计稿不需要进行任何转换即可适配。750设计稿量是多少就是多少,如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx =375px = 750物理像素,1rpx = 0.5px = 1物理像素。但是目前的方案还存在一定的问题,那就是非750的设计稿则需要进行一次换算,如640的设计稿就需要进行一次换算在640设计稿中的1rpx = 640/750rpx,而在WXSS中并不支持算术运算符,所以小程序的视觉设计稿尽量使用750来给出。

>> (3)样式级联如”element element”,微信团队回复说“级联会破坏掉组件的结构,级联最终会取消”,因此推荐使用BEM,即Block(块)、Element(元素)、Modifier(修饰符),是由Yandex团队提出的一种CSSClass命名方法。后续会提供另外的一种层级关系来解决依赖层级的情况。虽然现在还能使用级联的写法,但是最终可能会废弃,所以建议大家尽量不要使用级联,相信未来微信团队会尽快推出新的级联方案。

◆ 4.1 视图容器组件

>> 视图容器组件视图容器组件包括view、scroll-view、swiper及swiper-item,主要用于控制视图样式与内容展现

>> swiper-itemswiper-item为滑块项组件,仅可放置在swiper组件中,宽高自动设置为100%。

>> 基础内容组件包括icon、text和progress,用于在视图界面中展现图标、文本内容及进度条等信息

>> text为文本组件,是最常用的基础内容组件。它支持转义符”\”。text标签有点类似HTML中的span,组件内只支持text嵌套使用。同时,text是唯一可复制文本的标签。

>> 表单组件包括:button、form、input、checkbox、radio、picker、slider、switch和label,用于构建与用户交互的表单。

>> checkbox-group为多项选择器组件,内部由多个checkbox组成

>> form为表单组件,用于提交由用户输入的switch、input、checkbox、slider、radio、picker等组件值

>> textarea的blur事件会晚于页面上的tap事件,如果需要在button的点击事件获取textarea,可以使用form的bindsubmit

>> 互动操作组件包括:action-sheet、modal、toast、loading,用于实现让小程序应用对用户操作做出反馈,如菜单弹出、模态信息、通知及加载等待等

>> action-sheet是从屏幕底部出现的菜单表的组件,具有bindchange属性,类型为EventHandle,点击背景或action-sheet-cancel按钮时触发change事件,不携带数据

>> Navigator(导航组件)为页面链接组件。navigator类似于HTML中的a标签,但无target属性,默认跳转到新页面,redirect为在当前页面打开

>> navigator-hover默认为{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7; },navigator的子节点背景色应为透明色。

>> navigator组件可以帮助我们实现页面路由或跳转。

>> API方面,微信团队提供了页面路由的三个API方法:■wx.navigateTo(OBJECT):保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。■wx.redirectTo(OBJECT):关闭当前页面,跳转到应用内的某个页面。■wx.navigateBack():关闭当前页面,回退至前一页面。

>> 媒体组件包括image(图片)组件、audio(音频)组件、video(视频)组件。通过组件的应用,我们可以控制图片、音频、视频内容在页面上的显示方式及加载播放的进程

>> image为图片引用组件。image组件与传统HTML语言中的img类似,有一系列裁剪/缩放的属性

>> image组件默认宽度为300px、高度为225px。

>> 组件需要使用音频API:wx.createAudioContext来获取audio的上下文context

>> video标签认宽度300px、高度225px,设置宽高需要通过WXSS设置width和height。

>> ■canvas标签默认宽度为300px、高度为225px。■同一页面中的canvas-id不可重复,如果使用一个已经出现过的canvas-id,该canvas标签对应的画布将被隐藏并不再正常工作。

◆ 5.1 网络API

>> 目前微信团队提供了以下10个网络API接口:■wx.request(OBJECT)接口用于发起HTTPS请求。■wx.uploadfile(OBJECT)接口用于将本地资源上传到开发者服务器。■wx.downloadFile(OBJECT)接口用于下载文件资源到本地。■wx.connectSocket(OBJECT)接口用于创建一个WebSocket连接。■wx.onSocketOpen(CALLBACK)接口用于监听WebSocket连接打开事件。■wx.onSocketError(CALLBACK)接口用于监听WebSocket错误。■wx.sendSocketMessage(OBJECT)接口实现通过WebSocket连接发送数据。■wx.onSocketMessage(CALLBACK)接口实现监听WebSocket接收到服务器的消息事件。■wx.closeSocket()接口用于关闭WebSocket连接。■wx.onSocketClose(CALLBACK)接口用于实现监听WebSocket关闭。

>> ■小程序仅可以跟指定的域名进行网络通信,每个微信小程序需事先设置通信域名。
■一个微信小程序,同时只能有5个网络请求连接。
■网络请求的referer是不可以设置的,格式固定为https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid} 为小程序的appid, {version}为小程序的版本号,版本号为0表示为开发版。

>> 图片API主要实现对本地相册图片或相机拍照图片的处理,目前包括3个API接口:■wx.chooseImage(OBJECT)接口用于从本地相册选择图片或使用相机拍照。■wx.previewImage(OBJECT)接口用于预览图片。■wx.getImageInfo(OBJECT)接口用于获取图片信息。

>> 录音API提供了微信语音录制的能力,目前包括两个API接口:■wx.startRecord(OBJECT)接口实现开始录音。■wx.stopRecord()接口实现主动调用停止录音。

>> 音频播放控制API主要提供了对语音媒体文件的控制,包括播放、暂停、停止及audio组件的控制。分别是:■wx.playVoice(OBJECT)接口实现开始播放语音。■wx.pauseVoice()接口用于实现暂停正在播放的语音。■wx.stopVoice()接口实现结束播放语音。■wx.createAudioContext(audioId)接口创建并返回audio上下文audioContext对象,即audioId绑定一个audio组件。

>> 同时只允许一个语音文件正在播放,如果前一个语音文件还没播放完,将中断前一个语音播放。

>> 音乐播放控制API主要实现应用的背景音乐控制,比较适合一些游戏应用场景。共包括8个API:■wx.getBackgroundAudioPlayerState(OBJECT)接口用于获取音乐播放状态。■wx.playBackgroundAudio(OBJECT)用于播放音乐。■wx.pauseBackgroundAudio()接口实现暂停播放音乐。■wx.seekBackgroundAudio(OBJECT)接口用于控制音乐播放进度。■wx.stopBackgroundAudio()接口实现停止播放音乐。■wx.onBackgroundAudioPlay(CALLBACK)接口实现监听音乐播放。■wx.onBackgroundAudioPause(CALLBACK)接口实现监听音乐暂停。■wx.onBackgroundAudioStop(CALLBACK)接口实现监听音乐停止。

>> 页面导航API如下:■wx.setNavigationBarTitle(OBJECT):动态设置当前页面的标题。■wx.showNavigationBarLoading():接口实现在当前页面显示导航条加载动画。■wx.hideNavigationBarLoading():接口实现隐藏导航条加载动画。■wx.navigateTo(OBJECT):接口实现保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack()可以返回到原页面。■wx.redirectTo(OBJECT):接口实现关闭当前页面,跳转到应用内的某个页面。■wx.switchTab(OBJECT):接口实现跳转tabBar页面并关闭其他所有非tabBar页面。■wx.navigateBack(OBJECT):接口实现关闭当前页面,回退前一页面或多级页面。可通过getCurrentPages())获取当前的页面栈,决定需要返回几层。

>> ■wx.navigateTo和wx.redirectTo不允许跳转到tabbar页面,只能用wx.switchTab跳转到tabbar页面。■为了不让用户在使用小程序时造成困扰,微信团队规定页面路径只能是五层,请尽量避免多层级的交互方式。

>> 分享图片不能自定义;会取当前页面,从顶部开始,高度为80%屏幕宽度的图像作为分享图片。