一,基本配置
一个小程序里边有下列不同类型的文件:
- .json后缀的JSON配置文件
- .wxml后缀的WXML模板文件
- .wxss后缀的WXSS样式文件
- .js后缀的JS脚本逻辑文件
JSON配置
JSON是一种数据格式,并不是编程语言,在小程序中,JSON扮演静态配置的角色。
app.json中进行全局配置,包括小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。
1 | { |
注意:
- json中不能写注释
- pages中第一个字段为小程序的首页
- 可以通过在pages中写代码添加页面
- tabBar中list的第一项必须是pages中的第一项
JSON语法
JSON文件都是被包裹在一个大括号{}
,通过key-value
的方式表达数据。key必须包裹在一个双引号中。JSON的值只能是一下几种数据格式,其他任何格式都会触发报错。
1 | 1. 数字,包含浮点数和整数 |
WXML模板
WXML充当类似HTML的角色。将div
标签替换为view
标签。
多了wx:if
之类的渲染语法,以及{{ }}
表达式。将渲染与逻辑分离。比如:
1, 数据绑定
1 | <!--WXML--> |
1 | /*JS*/ |
JS只需要管理状态即可。
通过{{ }}
的语法把一个变量绑定到界面上,称为数据绑定。
2,列表渲染
1 | <!--WXML--> |
1 | /*Page.js*/ |
3,条件渲染
1 | <!--wxml--> |
1 | /*Page*/ |
WXSS样式
WXSS具有CSS大部分的特性,小程序在WXSS也做了一些扩充与修改。
WXSS
在底层支持新的尺寸单位rpx
,开发者可以免去换算像素的烦恼。规定所有的屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。提供了全局的样式和局部样式,支持样式导入(@import语句)
1
2
3
4/** common.wxss **/
.small-p{
padding:5px;
}1
2
3
4
5/** app.wxss **/
@import "common.wxss";
.middle-p{
padding:15px;
}
常见的选择器有且不限于以下几种:
JS逻辑交互
仅有界面展示是不够的,通过编写JS脚本文件来处理用户的操作。比如:
1 | <view>{{ msg }}</view> |
点击button按钮时,我们希望把上面msg的内容显示成"Hello World",于是我们在button上声明一个属性bindtap,在JS文件中声明了clickMe方法来响应这次点击操作:
1 | Page({ |
二,小程序宿主环境
我们称微信客户端给小程序所提供的环境为宿主环境。小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能。
渲染层和逻辑层
小程序运行环境分成渲染层和逻辑层,其中WXML模板和WXSS样式工作在渲染层,JS脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由两个线程管理:渲染层界面使用WebView进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程。
这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
通过app.json的pages字段可以知道当前小程序的所有页面路径:
1 | { |
其中,第一个字段表示小程序的首页。于是微信客户端把首页代码装载,通过小程序底层机制,渲染出首页。
小程序启动之后,在app.js定义的App实例的onLaunch回调会被执行:
1 | App({ |
整个小程序只有一个App实例,是全部页面共享的。
下面来说说小程序的一个页面是怎么写的:
1 | Page({ |
Page是一个页面构造器,这个构造器生成了一个页面。生成页面的时候,小程序框架会把data数据和index.wxml一起渲染出最终的结构,于是就得到了小程序的样子。
在渲染界面之后,页面实例就会收到一个onLoad的回调,可以在这个回调处理自己的逻辑。
组件
小程序提供了丰富的基础组件给开发者,开发者可以像搭积木一样,组合各种组件拼合成自己的小程序。
API
为了让开发者可以很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了很多 API 给开发者去使用。
需要注意的是:多数 API 的回调都是异步,你需要处理好代码逻辑的异步问题。
三,事件
什么是事件?
- 事件是视图层到逻辑层的通讯方式
- 事件可以将用户的行为反馈到逻辑层进行处理
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数
- 事件对象可以携带额外信息。如id, dataset, touches。
事件的使用方式
在组件中绑定一个事件处理函数
如bindtap,当用户点击该组件时,会在该页面对应的Page中找到相应的事件处理函数
1
<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
在相应的Page定义中写上相应的事件处理函数,参数是event
1
2
3
4
5Page{
tapName:function(event){
console.log(event)
}
}
事件分类
事件分为冒泡事件和非冒泡事件
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递
WXML冒泡事件列表:
类型 | 触发条件 | 最低版本 |
---|---|---|
touchstart | 手指触摸动作开始 | |
touchmove | 手指触摸后移动 | |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | |
touchend | 手指触摸动作结束 | |
tap | 手指触摸后马上离开 | |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 | [1.5.0] |
longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) | |
transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 | |
animationstart | 会在一个 WXSS animation 动画开始时触发 | |
animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 | |
animationend | 会在一个 WXSS animation 动画完成时触发 | |
touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 | [1.9.90] |
注:除上表以外的其他组件自定义事件如无特殊声明都是非冒泡事件,如form的submit事件,input的input事件,scroll-view的scroll事件等
绑定数据
在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。在WXML中,这些自定义数据以data-开头,多个单词由连字符-连接。
这种写法中,连字符写法会转换成驼峰写法,而大写子符会自动转成小写字符,如:
- data-element-type,最终呈现为 event.currentTarget.dataset.elementType;
- data-elementType,最终呈现为 event.currentTarget.dataset.elementtype.
四,云开发
云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。
初始化云程序
在project.config.json中添加"cloudfunctionRoot": "<云函数目录>/"
项目根目录处创建文件夹 <云函数目录>,并配置当前环境
在app.js的onLaunch中进行云函数初始化
1
2
3
4
5
6
7
8
9// 云开发初始化
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
env: 'zzmine-3cgx9',
traceUser: true,
})
}
云数据库
云开发提供了一个 JSON 数据库,顾名思义,数据库中的每条记录都是一个 JSON 格式的对象。
一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。每个数据表都有权限设置。
每条记录都有一个 _id
字段用以唯一标志一条记录、一个
_openid
字段用以标志记录的创建者,即小程序的用户。需要特别注意的是,在管理端(控制台和云函数)中创建的不会有
_openid
字段,因为这是属于管理员创建的记录。
数据库 API 分为小程序端和服务端两部分,小程序端 API 拥有严格的调用权限控制,开发者可在小程序内直接调用 API 进行非敏感数据的操作。对于有更高安全要求的数据,可在云函数内通过服务端 API 进行操作。云函数的环境是与客户端完全隔离的,在云函数上可以私密且安全的操作数据库。
注意:在小程序端直接使用数据库API一次最多拿到20条数据;要一次取出超过20条数据那么就得写成云函数(云函数中没有wx前缀)
使用 API 操作数据库只需三步:获取数据库引用、构造查询/更新条件、发出请求。以下是一个在小程序中查询数据库的发表于美国的图书记录的例子:
1 | // 1. 获取数据库引用 |
上传数据至云数据库:
1 | const DB = wx.cloud.database().collection("list") |
查询数据:
1 | //可以用where也可以.doc("_id") |
删除云数据库中的数据:
1 | delData:function(){ |
更新云端数据:
1 | updateInfo:function(){ |
云开发数据库提供以下几种数据类型:
1 | String:字符串 |
从云函数调用一次获取20条以上信息:
1 | // 云函数 |
1 | // 调用云函数获取云端数据 |
注意适当地修改云数据库的权限
云存储
图片上传:
1 | uploadImage:function(){ |
视频上传:
1 | uploadVideo:function(){ |
带有云后台的小程序进行多人协作
- 将所有开发者在微信小程序后台里面设置权限
- 在微信开发工具导入项目的时候使用同一个appid(wx9e2d10f6dc0c617f)
- 这样子之后,新的项目人员需要在cloudfunction文件夹右键配置云环境,过个几分钟应该就可以编译预览了
- 使用git作为版本管理工具,同步多人的代码。需添加github账号成为共同开发者
注意:上传多张图片到云后台需要加同步锁Promise
穷举获取云函数的ip
有时我们希望能够获取到服务器的公网IP,比如用于IP地址的白名单,或者想根据IP查询到服务器所在的地址,ipify就是一个免费好用的依赖,通过它我们也可以获取到云函数所在服务器的公网IP。
建立云函数getip, 然后输入以下代码。同时在package.json的”dependencies”里新增 "ipify":"latest"。
1 | const cloud = require('wx-server-sdk') |