
什么是小程序
微信创始人张小龙说:小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫后者搜一下即可打开应用。也提现了“用完即走”的理念,用户不用关系是否安装太多应用的问题。应用将无处不在,随时可用,担又无需安装卸载。
了解小程序
相关文档
分为服务号、订阅号、小程序三大账号体系。其中服务号是给企业和组织提供更强大的业务服务与用户管理能力,帮助企业快速实现全新的公众号服务平台。订阅号是为媒体和个人提供一种新的信息传播方式,构建与读者之间更好的沟通与管理模式。小程序是一种新开放能力,可以在微信内被便捷地获取和传播,同时具有出色的使用体验。
开发准备
代码构成
- json 后缀的 JSON 配置文件
 - wxml 后缀的 WXML 模板文件
 - wxss 后缀的 WXSS 样式文件
 - js 后缀的 JS 脚本逻辑文件
 
json配置文件
app.json1
2
3
4
5
6
7
8
9
10
11
12{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  }
}
index.json1
2
3{
  "enablePullDownRefresh": false
}
WXML 模板文件
index.wxml1
2
3
4
5
6
7
8
9
10
11
12<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>
WXSS 样式文件
1  | .userinfo {  | 
JS 脚本逻辑文件
1  | //index.js  | 
生命周期
应用生命周期
| 属性 | 类型 | 描述 | 触发时机 | 
|---|---|---|---|
| onLaunch | Function | 生命周期函数–监听小程序初始化 | 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) | 
| onShow | Function | 生命周期函数–监听小程序显示 | 当小程序启动,或从后台进入前台显示,会触发 onShow | 
| onHide | Function | 生命周期函数–监听小程序隐藏 | 当小程序从前台进入后台,会触发 onHide | 
| onError | Function | 错误监听函数 | 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 | 
| onPageNotFound | Function | 页面不存在监听函数 | 当小程序出现要打开的页面不存在的情况,会带上页面信息回调该函数,详见下文 | 
| 其他 | Any | 开发者可以添加任意的函数或数据到 | Object 参数中,用 this 可以访问 | 
页面生命周期、初始数据、事件处理函数
| 属性 | 类型 | 描述 | 
|---|---|---|
| data | Object | 页面的初始数据 | 
| onLoad | Function | 生命周期函数–监听页面加载 | 
| onReady | Function | 生命周期函数–监听页面初次渲染完成 | 
| onShow | Function | 生命周期函数–监听页面显示 | 
| onHide | Function | 生命周期函数–监听页面隐藏 | 
| onUnload | Function | 生命周期函数–监听页面卸载 | 
| onPullDownRefresh | Function | 页面相关事件处理函数–监听用户下拉动作 | 
| onReachBottom | Function | 页面上拉触底事件的处理函数 | 
| onShareAppMessage | Function | 用户点击右上角转发 | 
| onPageScroll | Function | 页面滚动触发事件的处理函数 | 
| onTabItemTap | Function | 当前是 tab 页时,点击 tab 时触发 | 
| 其他 | Any | 开发者可以添加任意的函数或数据到 object 参数中,在页面的函数中用 this 可以访问 | 
路由相关
| 路由方式 | 触发时机 | 路由前页面 | 路由后页面 | 
|---|---|---|---|
| 初始化 | 小程序打开的第一个页面 | onLoad, onShow | |
| 打开新页面 | 调用 API wx.navigateTo 或使用navigator组件 | onHide | onLoad, onShow | 
| 页面重定向 | 调用 API wx.redirectTo 或使用navigator组件 | onUnload | onLoad, onShow | 
| 页面返回 | 调用 API wx.navigateBack 或使用navigator组件 | 或用户按左上角返回按钮 onUnload | onShow | 
| Tab 切换 | 调用 API wx.switchTab 或使用navigator组件 | 或用户切换 Tab | 各种情况请参考下表 | 
| 重启动 | 调用 API wx.reLaunch 或使用navigator组件 | onUnload | onLoad, onShow | 
1  | <navigator open-type="navigateTo"/>  | 
基本语法
数据绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来。1
<view> {{ message }} </view>
1  | Page({  | 
三元运算1
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算1
<view> {{a + b}} + {{c}} + d </view>
1  | Page({  | 
逻辑判断1
<view wx:if="{{length > 5}}"> </view>
列表渲染
1  | <view wx:for="{{array}}">  | 
1  | Page({  | 
使用 wx:for-item 可以指定数组当前元素的变量名,
使用 wx:for-index 可以指定数组当前下标的变量名:
条件渲染
在框架中,使用 wx:if=”“ 来判断是否需要渲染该代码块:1
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 来添加一个 else 块:1
2
3<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 1
2
3
4<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>
事件处理
- 事件是视图层到逻辑层的通讯方式。
 - 事件可以将用户的行为反馈到逻辑层进行处理。
 - 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
 - 事件对象可以携带额外信息,如 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)
  }
})
可以看到log出来的信息大致如下: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
31
32
33
34{
"type":"tap",
"timeStamp":895,
"target": {
  "id": "tapTest",
  "dataset":  {
    "hi":"WeChat"
  }
},
"currentTarget":  {
  "id": "tapTest",
  "dataset": {
    "hi":"WeChat"
  }
},
"detail": {
  "x":53,
  "y":14
},
"touches":[{
  "identifier":0,
  "pageX":53,
  "pageY":14,
  "clientX":53,
  "clientY":14
}],
"changedTouches":[{
  "identifier":0,
  "pageX":53,
  "pageY":14,
  "clientX":53,
  "clientY":14
}]
}
引用
import可以在该文件中使用目标文件定义的template,如:
在 item.wxml 中定义了一个叫item的template:1
2
3
4<!-- item.wxml -->
<template name="item">
  <text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:1
2<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
WXS 模块
每一个 .wxs 文件和 
每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。
一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。1
2
3
4
5
6
7
8
9
10// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";
1  | <wxs src="./../tools.wxs" module="tools" />  | 
页面输出:1
2some msg
'hello world' from tools.wxs
自定义组件

js配置文件
1  | {  | 
wxml布局文件编写
1  | <view class='wx-dialog-container' hidden="{{!isShow}}">  | 
wxss样式文件
1  | .wx-mask {  | 
js核心文件
1  | Component({  | 
断点调试
