微信小程序框架接口
App 函数
在微信小程序中,若要在微信小程序启动、显示、隐藏时执行某些操作,或者在各个页面中需要共享一些数据时,可以通过 App 函数来实现。
App 函数用于注册一个微信小程序,该函数必须在 微信小程序入口文件(app.js)中调用,且只能调用一次。
JavaScript
App({})
App 函数的参数时一个对象,通过该对象可以指定应用生命周期回调函数和保存一些共享数据。
App 函数中的基本生命周期回调函数:
| 名称 | 描述 |
|---|---|
| onLaunch | 监听微信小程序初始化,微信小程序初始化完成时触发,全局只触发一次 |
| onShow | 监听微信小程序启动或切前台,微信小程序启动或从后台进入前台时触发 |
| onError | 错误监听函数,微信小程序脚本错误或者 API 调用报错时触发 |
| onHide | 监听微信小程序切后台,微信小程序从前台进入后台时触发 |
| onPageNotFound | 页面不存在监听函数,微信小程序要打开的页面不存在时触发 |
在页面的 JS 文件中,通过 getApp 函数可以获取微信小程序全局唯一的 App 实例。通过 getApp 函数获取 App 实例后,可以访问 App 实例的属性或调用 App 实例的方法。
获取 App 实例的基本用法:
JavaScript
const app = getApp()
Page 函数
在微信小程序中,页面交互的代码写在页面 JS 文件中,每个页面都需要通过 Page 函数进行注册。
-
Page 函数只能写在微信小程序每个页面对应的 JS 文件中,并且每个页面只能注册一个。
-
Page 函数的参数是一个对象,通过该对象可以指定页面初始数据、页面生命周期回调函数和页面事件处理函数。
Page 函数的基本用法:
JavaScript
Page({
// 页面初始数据
data: {},
// 页面生命周期回调函数
onLoad() { },
// 页面事件处理函数
onPullDownRefresh() { }
// ...
})
页面初始数据
微信小程序提供了 Mustache 语法(双大括号语法)用于实现数据绑定,可将 data 中的数据通过 Mustache 语法输出到页面上。
示例:页面初始数据
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
message: 'hello, world~'
}
})
首页页面结构(pages/index/index.wxml):
HTML
<text>{{message}}</text>
示例效果:

页面生命周期
在微信小程序中,页面的生命周期是指每个页面"加载 → 渲染 → 销毁"的过程,每个页面都有生命周期,如果想要在某个特定的时机进行特定的处理,则可以通过页面生命周期回调函数来完成。
页面生命周期回调函数用于实现在特定的时间点执行特定的操作,随着页面生命周期的变化,页面生命周期回调函数会自动执行。
微信小程序的基本页面生命周期回调函数:
| 名称 | 描述 |
|---|---|
| onLoad | 页面加载时触发,且一个页面只会在创建完成后调用一次 |
| onShow | 页面显示时触发 |
| onReady | 页面初次渲染完成时触发,一个页面只会调用一次 |
| onHide | 页面隐藏时触发 |
| onUnload | 页面卸载释放时触发 |
示例:页面生命周期
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
onLoad() {
console.log('页面加载')
},
onShow() {
console.log('页面显示')
}
})
示例效果:

页面事件处理函数
页面事件处理函数用于监听用户的行为,如上拉、下拉、滚动页面等。
微信小程序的基本页面事件处理函数:
| 名称 | 描述 |
|---|---|
| onPullDownRefresh | 监听用户下拉刷新事件 |
| onReachBottom | 监听页面上拉触底事件 |
| onPageScroll | 监听页面滚动事件 |
| onShareAppMessage | 用户点击右上角三点,选择转发给朋友时触发事件 |
上拉触底
在微信小程序中,通过手指在屏幕上的上拉滑动操作,当滚动条到达距离页面底部特定的距离时,就会触发上拉触底事件,从而可以加载更多数据或执行相关的操作。
微信小程序提供了 onReachBottom 事件处理函数,用于监听当前页面的上拉触底事件。
在默认情况下,触发上拉触底事件时,滚动条距离页面底部的距离为 50px,即上拉触底距离为 50px,在全局配置文件(app.json)或页面配置文件(pages/xxx/xxx.json)中可以修改上拉触底的距离。
示例:上拉触底
全局配置文件(app.json):
JSON
"window": {
"onReachBottomDistance": 20
}
首页页面配置文件(pages/index/index.json):
JSON
{
"onReachBottomDistance": 20
}
首页页面结构(pages/index/index/wxml):
HTML
<navigation-bar title="Weixin" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<view>
<text>枯藤老树昏鸦\n</text>
<text>小桥流水人家\n</text>
<text>古道西风瘦马\n</text>
<text>夕阳西下\n</text>
<text>断肠人在天涯\n\n</text>
<!-- ... -->
</view>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
onReachBottom: function() {
console.log("滑到最底部啦...")
}
})
示例效果:

下拉刷新
在微信小程序中,通过手指在屏幕上的下拉滑动操作,当下拉页面达到顶部时,再进行下拉,从而实现页面数据的重新加载。
微信小程序提供了 onPullDownRefresh 事件处理函数,用于监听当前页面的下拉刷新事件。
在默认情况下,微信小程序没有启用下拉刷新,在全局配置文件(app.json)或页面配置文件(pages/xxx/xxx.json)中可以启用下拉刷新。
示例:下拉刷新
全局配置文件(app.json):
JSON
"window": {
"enablePullDownRefresh": true
},
首页页面配置文件(pages/index/index.json):
JSON
{
"enablePullDownRefresh": true
}
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
onPullDownRefresh() {
console.log("下拉刷新啦...")
}
})
示例效果:

事件绑定
在微信小程序中,事件是视图层到逻辑层的通信方式,通过给组件绑定事件,可以监听用户的操作行为,然后在对应的事件处理函数中进行相应的业务处理。
若要为组件绑定事件,可以通过为组件添加"bind + 事件名称"、"bind: + 事件名称"、"catch + 事件名称"、"catch: + 事件名称"属性来完成,属性的值为事件处理函数,当组件的事件被触发时,会主动执行事件处理函数。
bind 和 catch 的区别在于 bind 绑定的事件不会阻止冒泡事件向上冒泡,而 catch 绑定的事件可以阻止冒泡事件向上冒泡。
微信小程序的基本事件:
| 类别 | 名称 | 描述 |
|---|---|---|
| 点击事件 | tap | 手指触摸后马上离开时触发 |
| 长按事件 | longpress | 手指触摸后,超过 350ms 再离开时触发 如果指定了事件回调函数并触发了这个事件,tap 事件将不被触发 |
| 触摸事件 | touchstart | 手指触摸动作开始时触发 |
| touchmove | 手指触摸后移动时触发 | |
| touchcancel | 手指触摸动作被打断时触发 | |
| touchend | 手指触摸动作结束时触发 | |
| 其他事件 | input | 键盘输入时触发 |
| submit | 携带 form 组件中的数据触发 submit 事件 |
示例:事件绑定
首页页面结构(pages/index/index.wxml):
HTML
<button bindtap="showMessage">点我弹出消息</button>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
showMessage() {
console.log("按钮被点击啦")
}
})
示例效果:

事件对象
当事件处理函数被调用时,微信小程序会将事件对象以参数的形式传给事件处理函数。
事件对象的基本属性:
| 名称 | 描述 |
|---|---|
| type | 事件类型 |
| timeStamp | 事件生成的时间戳 |
| target | 触发该事件的源头组件的一些属性值的集合,实际触发事件的组件 具体指向触发事件的元素,这个元素有可能是子组件,也有可能是父组件,主要取决于执行动作的区域 |
| currentTarget | 当前事件所绑定的组件的一些属性值的集合,即事件绑定所在的组件 无论点击的是子元素还是父元素,其始终指向绑定了该事件的组件 |
| mark | 事件标记数据 |
| detail | 自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入等 |
示例:事件对象
首页页面结构(pages/index/index.wxml):
HTML
<input id="userName" style="border: 1px solid #000000" placeholder="请输入内容" bindinput="input" />
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
input(e) {
console.log(e)
}
})
示例效果:

data-* 自定义属性
微信小程序事件处理函数在执行时,可以通过自定义属性来进行传参。
data-* 是一个自定义属性,data-* 自定义属性实际上是由 data- 前缀加上一个自定义的属性名组成的,属性名中如果有多个单词,用连字符"-"连接,属性值表示要传参的数据。
在事件处理函数中通过 target 或 currentTarget 对象的 dataset 属性可以获取 data-* 自定义属性的数据。
示例:data- 自定义属性*
首页页面结构(pages/index/index.wxml):
HTML
<button data-id="1" data-nick-name="多仔" bindtap="showInfo">点我获取信息</button>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
showInfo(e) {
console.log("id:" + e.target.dataset.id)
console.log("nickName:" + e.target.dataset.nickName)
}
})
示例效果:

this 关键字
在微信小程序开发过程中,有时需要在函数中访问页面中定义的一些数据,或者调用页面中定义的一些函数,此时可以通过 this 关键字来实现,this 关键字代表当前页面对象。
示例:this 关键字
首页页面结构(pages/index/index.wxml):
HTML
<button bindtap="showInfo">点我获取信息</button>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
nickName: "多仔"
},
hello() {
console.log("欢迎访问我的小程序")
},
showInfo() {
this.hello()
console.log("我的昵称是:" + this.data.nickName)
}
})
示例效果:

setData 函数
为了实现在数据变化时使页面同步更新,微信小程序提供了 setData 函数,可以立即改变 data 中的数据,并通过异步的方式将数据渲染到页面上。
直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
setData 函数的基本用法:
JavaScript
this.setData({数据键: 数据值}, [页面更新渲染完毕后的回调函数])
示例:setData 函数
首页页面结构(pages/index/index.wxml):
HTML
<input style="border: 1px solid #000000;" placeholder="请输入内容" bindinput="input1" />
<text>以上输入框输入的内容是:{{content1}}</text>
<text>\n\n</text>
<input style="border: 1px solid #000000;" placeholder="请输入内容" bindinput="input2" />
<text>以上输入框输入的内容是:{{content2}}</text>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
content1: "",
content2: ""
},
input1(e) {
this.data.content1 = e.detail.value
},
input2(e) {
this.setData({
content2: e.detail.value
})
}
})
示例效果:

模块化
在微信小程序中,为了提高代码的可复用性,通常会将一些公共的代码抽离成单独的 JS 文件,作为模块使用,每一个 JS 文件均为一个模块。
创建模块的基本用法:
JavaScript
module.exports = {
...
}
引入模块的基本用法:
JavaScript
var 模块名称 = require("模块文件路径")
示例:模块化
日志模块(utils/log.js):
JavaScript
module.exports = {
debug(message) {
console.log("[调试日志]", message)
},
warning(message) {
console.log("[警告日志]", message)
}
}
首页页面逻辑(pages/index/index.js):
JavaScript
var log = require("../../utils/log")
Page({
onLoad() {
log.debug("debug message")
log.warning("warning message")
}
})
示例效果:

WXML 语法基础
双向数据绑定
在 WXML 中,普通的属性的绑定是单向的。
在表单处理中,使用表单事件 + setData 函数,可以立即改变 data 中的数据,并通过异步的方式将数据渲染到页面上以实现双向数据绑定,但该方法较为复杂。
微信小程序提供了简易双向绑定机制,可以快速实现双向数据绑定,简易双向绑定机制的属性值只能是一个单一字段的绑定,不能写 data 路径,不支持数组和对象的写法。
简单双向绑定的基本用法:
HTML
<input model:value="{{...}}"/>
示例:双向数据绑定
首页页面结构(pages/index/index.wxml):
HTML
<input style="border: 1px solid #000000;" placeholder="请输入内容" model:value="{{content}}" />
<text>以上输入框输入的内容是:{{content}}</text>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
content: ""
}
})
示例效果:

条件渲染
在微信小程序开发过程中,如果需要根据不同的判断结果显示不同组件,可以使用条件渲染来实现,条件渲染通过标签的 wx:if 控制属性来完成。
wx:if 属性的基本用法:
HTML
<view wx:if="{{ 判断条件 }}">...</view>
<view wx:elseif="{{ 判断条件 }}">...</view>
<view wx:else>...</view>
block 标签
当使用一个判断条件决定是否显示或隐藏多个组件时,可以使用 block 标签将多个组件包裹起来。
block 标签可以创建一个容器,该标签并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接收控制属性,提高渲染性能。
block 标签的基本用法:
HTML
<block wx:if="{{ 判断条件 }}">
<view>...</view>
<view>...</view>
</block>
示例:block 标签
首页页面结构(pages/index/index.wxml):
HTML
<block wx:if="{{isShow}}">
<text>hello,微信小程序</text>
</block>
<button bind:tap="show">点我显示/隐藏</button>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
isShow: false
},
show() {
this.setData({
isShow: !this.data.isShow
})
},
})
示例效果:

hidden 属性
hidden 属性也可以控制组件的显示与隐藏。
hidden 属性的基本用法:
HTML
<view hidden="{{ 判断条件 }}">...</view>
hidden 与 wx:if 的区别:
- wx:if 控制属性的初始渲染条件为 false,只有条件第一次变为 true 的时候才开始渲染,hidden 属性所在的组件始终会被渲染,只是简单的控制显示与隐藏。
- wx:if 控制属性有更大的切换开销而 hidden 属性有更高的初次渲染开销。
- 在需要频繁切换显示和隐藏的情境下用 hidden 更好,而如果运行时条件不太可能会改变则用 wx:if 控制属性更好。
列表渲染
列表渲染通过 wx:for 控制属性来实现。
wx:for 属性的基本用法:
HTML
<view wx:for="{{要遍历的数组}}"
wx:for-item="遍历元素别名,默认为item"
wx:for-index="遍历元素下标变量名,默认为index"
wx:key="唯一标识符"></view>
wx:key 属性用于为每一项设置唯一标识,提高列表渲染的效率。
- item 本身是一个具有唯一性的字符串或数字,唯一标识符可以是 *this 表示 item 本身。
- item 本身是一个对象,唯一标识符可以是对象中的一个值具有唯一性的属性的名称。
示例:列表渲染
首页页面结构(pages/index/index.wxml):
HTML
<view wx:for="{{userList}}" wx:key="id">
{{item.id}} -> {{item.userName}}
</view>
首页页面逻辑(pages/index/index.js):
JavaScript
Page({
data: {
userList: [
{
id: 1,
userName: "唐僧"
},
{
id: 2,
userName: "孙悟空"
},
{
id: 3,
userName: "猪悟能"
},
{
id: 4,
userName: "沙悟净"
}
]
}
})
示例效果:

include 标签
include 标签用于引用其他文件的 WXML 代码,相当于把引用的代码复制到 include 标签的位置。
include 标签的基本用法:
HTML
<include src="WXML文件路径" />
示例:include 标签
首页头部结构(pages/index/header.wxml):
HTML
<swiper>
<swiper-item>
<view style="background-color: blue; height: 200px;">0</view>
</swiper-item>
<swiper-item>
<view style="background-color: green; height: 200px;">1</view>
</swiper-item>
<swiper-item>
<view style="background-color: red; height: 200px;">2</view>
</swiper-item>
</swiper>
首页底部结构(pages/index/footer.wxml):
HTML
<view style="margin-top: 120rpx; text-align: center;">
©️ 版权所有
</view>
首页页面结构(pages/index/index.wxml):
HTML
<include src="header.wxml"/>
<view>
欢迎访问我的小程序
</view>
<include src="footer.wxml" />
示例效果:

WXS
WXS 概述
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXS 主要用于在视图层(WXML)中运行类 JavaScript 脚本,以实现对数据的处理和变换,避免了跨线程通信的开销。
WXS 的特点:
- WXS 在设计时借鉴了 JavaScript 的语法,但是 WXS 和 JavaScript 本质上是完全不同的两种语言。
- WXS 有 8 种数据类型,包括 number 数值、string 字符串、boolean 布尔、object 对象、function 函数、array 数组、date 日期、regexp 正则。
- WXS 不支持 let、const、解构赋值、展开运算符、尖头函数、对象属性简写等语法,WXS 支持 var 定义变量、普通 function 函数等语法。
- WXS 遵循 CommonJS 规范。
- WXS 经常与 Mustache 语法配合使用,但是在 WXS 中定义的函数不能作为组件的事件回调函数。
- WXS 代码运行的环境和其他 JavaScript 代码运行的环境是隔离的,在 WXS 代码中不能调用页面的 JS 文件定义的函数,不能调用微信小程序提供的 API。
- WXS 代码在 iOS 设备上的执行速度比 JavaScript 快 2-20 倍,在 Android 设备上的执行速度和 JavaScript 无差异。
WXS 使用
WXS 代码可以写在页面的 WXML 文件的 wxs 标签内(即内嵌 WXS 脚本),也可以写在以 .wxs 为后缀名的文件中(外联 WXS 脚本)。
每一个 wxs 标签和 .wxs 文件均视为一个单独的模块,有自己独立的作用域。
内嵌 WXS 脚本的基本用法:
HTML
<wxs module="模块名称">
module.exports = {
...
}
<wxs>
外联 WXS 脚本的基本用法:
HTML
<wxs module="模块名称" src="WXS文件路径"></wxs>
示例:WXS
字符串工具脚本(utils/strutil.wxs):
JavaScript
module.exports = {
toUpperCase: function(str) {
return str.toUpperCase()
}
}
首页页面结构(pages/index/index.wxml):
HTML
<wxs module="strutil1" src="../../utils/strutil.wxs"></wxs>
<wxs module="strutil2">
module.exports = {
toLowerCase: function(str) {
return str.toLowerCase()
}
}
</wxs>
<view>{{strutil1.toUpperCase("weixin")}}</view>
<view>{{strutil2.toLowerCase("WEIXIN")}}</view>
示例效果:
