创建小程序
新建项目选择小程序项目,选择代码存放的硬盘路径,填入刚刚申请到的小程序的 AppID,给你的项目起一个好听的名字,最后,勾选 "创建 QuickStart 项目" (注意: 你要选择一个空的目录才会有这个选项),点击确定,你就得到了你的第一个小程序了,点击顶部菜单编译就可以在 IDE 预览你的第一个小程序。
框架
小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。一个小程序主体部分由app.js,app.json,app.wxss组成,必须放在项目的根目录
其中:
app.js 表示小程序逻辑
app.json 表示小程序公共设置
app.wxss 表示小程序公共样式表(可选)
一个小程序页面由四个文件组成,分别是:
js :页面逻辑
wxml: 页面结构
wxss: 页面样式(可选)
json: 页面配置(可选)
配置
app.json文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。
以下是一个包含了所有配置选项的 app.json :
{
"pages": [
"pages/index/index",
"pages/logs/index"
],
"window": {
"navigationBarTitleText": "Demo"
},
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
}, {
"pagePath": "pages/logs/logs",
"text": "日志"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
pages接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。
window用于设置小程序的状态栏、导航条、标题、窗口背景色。
注:HexColor(十六进制颜色值),如"#ff00ff"
tabBar如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面
其中 list 接受一个数组,数组中的每个项都是一个对象,其属性值如下:
逻辑层(App Service)
小程序开发框架的逻辑层由 JavaScript 编写。
逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
在 JavaScript 的基础上,我们做了一些修改,以方便地开发小程序。
App
App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。
getApp()
全局的 getApp() 函数可以用来获取到小程序实例。
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
Page
Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。
object 内容在页面加载时会进行一次深拷贝,需考虑数据大小对页面加载的开销
数据绑定
可以在page里通过WXML对数据进行绑定
<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
data: {
text: 'init data',
array: [{msg: '1'}, {msg: '2'}]
}
})
页面相关事件处理函数
onPullDownRefresh
: 下拉刷新
onReachBottom
: 上拉触底
onPageScroll
: 页面滚动,参数为scrollTop,可自定义页面在垂直方向已滚动的距离(单位px)
自定义转发字段
Page({
onShareAppMessage: function () {
return {
title: '自定义转发标题',
path: '/page/user?id=123'
}
}
})
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,可以构建出页面的结构(类似DOM结构)。用以下一些简单的例子来看看 WXML 具有什么能力:
数据绑定
<view> {{message}} </view>
列表渲染
等价于v-for
<view wx:for="{{array}}"> {{item}} </view>
条件渲染
通过判断view的值来进行选择渲染
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
Page({
data: {
view: 'MINA'
}
})
模板
先声明一个模板,通过模板标签调用
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
事件
等价于v-on
<view bindtap="add"> {{count}} </view>
Page({
data: {
count: 1
},
add: function(e) {
this.setData({
count: this.data.count + 1
})
}
})
数据绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
组件属性
<view id="item-{{id}}"> </view>
控制属性
<view wx:if="{{condition}}"> </view>
关键字
<checkbox checked="{{false}}"> </checkbox>
运算
可以在 {{}} 内进行简单的运算,支持的有如下几种方式:
三元运算
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算
<view> {{a + b}} + {{c}} + d </view>
逻辑判断
<view wx:if="{{length > 5}}"> </view>
组合
也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
列表渲染
wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
block wx:for
类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
事件
什么是事件
事件是视图层到逻辑层的通讯方式。
事件可以将用户的行为反馈到逻辑层进行处理。
事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
在组件中绑定一个事件处理函数。
如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
详细的事件如下
引用
WXML 提供两种文件引用方式import和include。
import
import可以在该文件中使用目标文件定义的template,如:
在 item.wxml 中定义了一个叫item的template:
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
import 的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
include
include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<view> header </view>
<view> footer </view>
wxss
WXSS 用来决定 WXML 的组件应该怎么显示。
与 CSS 相比,WXSS 扩展的特性有:
尺寸单位
样式导入
尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
样式导入
使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。
.small-p {
padding:5px;
}
@import "common.wxss";
.middle-p {
padding:15px;
}
组件
框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。
什么是组件
组件是视图层的基本组成单元。
组件自带一些功能与微信风格的样式。
一个组件通常包括开始标签和结束标签,属性用来修饰这个组件,内容在两个标签之内。
<tagname property="value">
Content goes here ...
</tagname>
view
视图容器相当于div,我们往里面写内容或嵌套标签
scroll-view
一块可以滚动的区域,可以通过修改属性实现滚动效果
swiper
轮播图
movable-view
可移动的视图容器,在页面中可以拖拽滑动
cover-view
覆盖在原生组件之上的文本视图,可覆盖的原生组件包括map、video、canvas、camera、live-player、live-pusher
camera
调用系统相机,需先调用wx.createCameraContext
wx.createCameraContext(this)
创建并返回 camera 上下文 cameraContext 对象,cameraContext 与页面的 camera 组件绑定,一个页面只能有一个camera,通过它可以操作对应的 <camera/> 组件。
// camera.js
Page({
takePhoto() {
const ctx = wx.createCameraContext()
ctx.takePhoto({
quality: 'high',
success: (res) => {
this.setData({
src: res.tempImagePath
})
}
})
},
error(e) {
console.log(e.detail)
}
})
API
wx.navigateTo保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面
wx.setNavigationBarTitle动态设置当前页面的标题。
wx.showLoading(OBJECT)显示 loading 提示框, 需主动调用 wx.hideLoading才能关闭提示框
自定义组件
类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。要编写一个自定义组件,首先需要在 json 文件中进行自定义组件声明
{
"component": true
}
组件的配置需要在.js文件里书写,通过
component
注册组件,并提供组件的属性定义、内部数据和自定义方法。
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod: function(){}
}
})
使用自定义组件
使用自定义组件,需要在调用组件的页面的.json文件里进行引用声明
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
组件模版
组件模版的写法与页面模板相同
组件模板中可以提供一个slot标签,可以获取到插入模板中的内容
<!-- 组件模板 -->
<view class="wrapper">
<view>这里是组件的内部节点</view>
<slot></slot>
</view>
<!-- 引用组件的页面模版 -->
<view>
<component-tag-name>
<!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
<view>这里是插入到组件slot中的内容</view>
</component-tag-name>
</view>
组件样式
组件对应 wxss 文件的样式,只对组件wxml内生效
指定组件默认样式可以使用:host
选择器
:host {
color: yellow;
}
Component构造器
Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。
定义段 | 类型 | 是否必填 | 描述 |
---|---|---|---|
properties | Object Map | 否 | 组件的对外属性,是属性名到属性设置的映射表,属性设置中可包含三个字段, type 表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数 |
data | Object | 否 | 组件的内部数据,和 properties 一同用于组件的模版渲染 |
methods | Object | 否 | 组件的方法,包括事件响应函数和任意的自定义方法 |
ready | Function | 否 | 组件生命周期函数,在组件布局完成后执行,此时可以获取节点信息 |
checkbox
多项选择器,内部由多个checkbox组成。
bindchange:<checkbox-group/>中选中项发生改变时触发 bindchange事件
可绑定的属性如下
属性名 | 类型 | 说明 |
---|---|---|
value | string | 发生change事件时,表示选中checkbox的标识 |
disabled | Boolean | 禁用 |
checked | Boolean | 是否选中状态 |
color | color | checkbox的颜色 |
<checkbox-group bindchange="checkboxChange">
<label class="checkbox" wx:for="{{items}}">
<checkbox value="{{item.name}}" checked="{{item.checked}}"/>{{item.value}}
</label>
</checkbox-group>
input
输入框,用法与HTML相同,具体属性参考微信小程序文档
label
用来关联其他表单元素,用法与HTML相同,提供for属性来查找id进行关联
picker
从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。
普通选择器
<view class="section__title">普通选择器</view>
<picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
<view class="picker">
当前选择:{{array[index]}}
</view>
</picker>
普通选择器提供以下属性进行修饰
属性名 | 类型 | 说明 |
---|---|---|
range | String | 表示进行选择的对象数组时,通过range-key来指定对象中的key值作为选择器显示内容 |
value | Number | 表示该值是range中的第几个(下标值) |
bindchange | event | value改变时触发的事件 |
bindcancel | event | 当取消选择或点遮罩层收起 picker 时触发 |
时间选择器
通过设定最小时间和最大时间,在该范围内进来时间选择
<view class="section__title">时间选择器</view>
<picker mode="time" value="{{time}}" start="09:01" end="21:01" bindchange="bindTimeChange">
<view class="picker">
当前选择: {{time}}
</view>
</picker>
时间选择器提供以下新属性
属性名 | 类型 | 说明 |
---|---|---|
value | string | 表示选中的时间 |
start | string | 表示有效时间范围的开始 |
end | string | 表示有效时间范围的结束,字符串格式为"hh:mm" |
选择器的联动
当我们需要实现通过选择省份后,市和区同时发生改变,可以通过bindcolumnchange方法来进行监听
<picker mode="multiSelector" bindcolumnchange="onColChange" bindchange="onpickerCha" range="{{arr2}}"value="{{index}}">
我的儿子是:{{arr2[0][index[0]]}}------{{arr2[1][index[1]]}}
</picker>
onColChange(e){
if(e.detail.value==1){
this.setData({
'arr2[1]':["aa","bb"]
})
}
if(e.detail.value==0){
this.setData({
'arr2[1]':["男","女"]
})
}
},
radio
radio-group
单项选择器,内部由多个<radio/>组成。
radio的属性同上checkbox
<radio-group class="radio-group" bindchange="radioChange">
<label class="radio" wx:for="{{items}}">
<radio value="{{item.name}}" checked="{{item.checked}}"/>{{item.value}}
</label>
</radio-group>
登录小程序
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。
wx.login
调用接口wx.login() 获取临时登录凭证(code)
可选参数如下
属性名 | 类型 | 说明 |
---|---|---|
timeout | Number | 超时时间,单位 ms |
success | Function | 接口调用成功的回调函数 |
fail | Function | 接口调用失败的回调函数 |
complete | Function | 接口调用结束的回调函数(调用成功、失败都会执行) |
其中success接收两个参数
errMsg表示成功调用的结果
code是成功调用后返回的用户登录凭证(有效期五分钟),开发者需要在开发者服务器后台调用 api,使用 code 换取 openid 和 session_key 等信息
App({
onLaunch: function() {
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://test.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
});
}
})
wx.getUserInfo
通过该接口可以拿到用户的个人信息,但是如果没有得到用户授权便调用该接口则直接报错
成功调用后的回调函数参数如下
参数 | 类型 | 说明 |
---|---|---|
userInfo | OBJECT | 用户信息对象,不包含 openid 等敏感信息 |
encryptedData | String | 包括敏感数据在内的完整用户信息的加密数据 |
iv | String | 加密算法的初始向量(如果需要获取用户的隐私信息则需要同时调用encryptedData和iv) |
获取到useInfo后你可以通过以下参数获取用户信息
属性名 | 类型 | 说明 |
---|---|---|
nickName | String | 用户昵称 |
city | String | 用户所在城市 |
province | String | 用户所在省份 |
country | String | 用户所在国家 |
language | String | 用户的语言,(简体中文为zh_CN) |
Page({
data: {
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
onLoad: function() {
// 查看是否授权
wx.getSetting({
success: function(res){
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function(res) {
console(res.userInfo)
}
})
}
}
})
},
bindGetUserInfo: function(e) {
console.log(e.detail.userInfo)
}
})
wx.showModal
显示模态弹窗,相当于提示框
wx.showModal({
title: '提示',
content: '这是一个模态弹窗',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
wx.requestPayment
发起微信支付
该接口有五个必填的属性
timeStamp:时间戳,即当前的时间
nonceStr:随机字符串,长度为32个字符以下,用来作标识
package:统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
signType:签名算法,暂支持 MD5
paySign:签名
通常情况下这五个数据都会由后台提供给我们
wx.createAnimation
创建一个动画实例
animation
调用实例的方法来描述动画。最后通过动画实例的export
方法导出动画数据传递给组件的animation
属性。
<view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view>
wx.createAnimation
可传四个参数分别是
属性名 | 类型 | 说明 |
---|---|---|
duration | 整数 | 动画的持续时间 |
timingFunction | string | 定义动画的效果 |
delay | 整数 | 动画的延迟播放时间 |
transformOrigin | string | 设置元素旋转的基点 |
animation
通过调用
wx.createAnimation
生成的动画对象animation
我们可以描述动画
可用属性请参考文档
step
当我希望在动画的第一步执行完后再执行第二步时,可以在执行完的动画后面加上
step()
来标识一组动画的完成。step
可以传入一个跟 wx.createAnimation() 一样的配置参数用于指定当前组动画的配置。
Page({
onShow: function(){
var animation = wx.createAnimation({
duration: 1000,
timingFunction: 'ease',
})
this.animation = animation
animation.scale(2,2).rotate(45).step()
this.setData({
animationData:animation.export()
})
}
})
wx.scanCode
当我们需要使用手机上的二维码时,可以通过调用该方法调起客户端扫码界面
// 允许从相机和相册扫码
wx.scanCode({
success: (res) => {
console.log(res)
}
})
// 只允许从相机扫码
wx.scanCode({
onlyFromCamera: true,
success: (res) => {
console.log(res)
}
})