wx.onWindowResize(function callback)
监听窗口尺寸变化的事件wx.setStorageSync('key', 'value')
向本地存储中写入内容$.ajax(option)
函数,需要通过 success、fail、complete 接收回调的结果wx.request()
发起网络数据请求,通过 success 回调函数接收数据数据绑定的基本原则
在 data 中定义数据
在 WXML 中使用数据
把 data 中的数据绑定到页面中渲染,使用 Mustache
语法(双大括号) 将变量包起来
Mustache 语法的使用场景
demo.js
Page({
data: {
src: 'www.baidu.com'
}
})
demo.wxml
<image src="{{ src }}">image>
demo.js
Page({
data: {
randomNum: Math.random()*10 // 生成 10 以内的随机数
}
})
deom.wxml
<view>{{ randomNum >= 5 ? '随机数字大于或等于5' : '随机数小于5' }}view>
事件是渲染层到逻辑层的通讯方式。通过事件可以将用户在渲染层的行为,反馈到逻辑层进行业务处理。
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap 或 band:tap | 手指触摸后马上离开,类似于 HTML 中的 |
input | bindinput 或 bind:input | 文本框的输入事件 |
change | bindchange 或 bind:change | 状态改变时触发 |
当事件回调触发的时候,会收到一个事件对象
event
,它的详细属性如下所示
target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。
点击内部的按钮,点击事件以冒泡的方式向外扩散,也会触发外层 view 的 tap 事件处理函数。
此时,对于外层的 view 来说:
e.target
指向的是触发事件得到源头组件,因此,e.target
是内部的按钮组件e.currentTarget
指向的是当前正在触发事件的那个组件,因此,e.currentTarget
是当前的 view 组件在小程序中,不存在 HTML 中的 onclick 鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为
通过 bindtap
,可以为组件绑定 tap 触摸事件
<button type="primary" bindtap="btnHandle">按钮button>
在页面的 .js
文件中定义对应的事件处理函数,事件参数通过形参 event
(一般简写成 e)来接受
Page({
// 定义按钮的事件处理函数
btnHandle(e) {
// 事件对象 event
console.log(e);
// 获取自定义属性(参数)
console.log(e.target.dataset.val);
}
})
通过调用
this.setData(dataObject)
方法,可以给页面 data 中的数据重新赋值
Page({
data: {
count: 0
}
// 修改 count 的值
changeCount() {
this.setData({
count: this.data.count + 1
})
}
})
可以为组件提供
data-*
自定义属性传参,其中 * 代表的是参数的名字
如果不使用 Mustache 语法(双大括号),参数 2 会被解析为字符串格式
<button type="primary" bindtap="btnHandle" data-val="{{2}}">事件传参button>
在事件处理函数中,通过
event.target.dataset.参数名
来获取到具体参数的值
btnHandle(e) {
// 获取自定义属性(参数)val
console.log(e.target.dataset.val);
}
在小程序中,通过
input
事件来响应文本框的输入事件
通过 bindinput
,可以为文本框绑定输入事件
<input bindinput="inputHandle" type="text"/>
在页面的 .js
文件中定义对应的事件处理函数
inputHandle(e) {
// 通过 e.detail.value 获取文本框最新的值,是变化过后的值
console.log(e.detail.value);
}
实现思路:
通过 this.setData()
将文本框的最新值(event.detail.value
)赋给 msg
具体步骤:
定义数据
Page({
data: {
msg: '你好'
}
})
渲染结构
绑定 input 事件处理函数
inputHandle(e) {
this.setData({
// 通过 e.detail.value 获取文本框最新的值
msg: e.detail.value
})
}
在小程序中,使用
wx:if="{{ condition }}"
来判断是否需要渲染该代码块
<view wx:if="{{ condition }}">Trueview>
也可以使用
wx:elif
和wx:else
来添加判断
<view wx:if="{{ type === 1 }}">男view>
<view wx:elif="{{ type === 2 }}">女view>
<view wx:else>保密view>
标签使用 wx:if如果要一次性控制多个组件的展示与隐藏,可以使用一个
标签将多个组件包装起来,并在
标签上使用
wx:if
控制属性。标签只起包裹作用,不参与页面渲染,相当于
vue
中的
<block wx:if="{{true}}">
<view>view1view>
<view>view2view>
block>
在小程序中,直接使用
hidden="{{ condition }}"
也能控制元素的现实与隐藏
<view hidden="{{ condition }}">条件为 true 隐藏,条件为 false 显示view>
wx:if
以动态创建和移除元素的方式,控制元素的展示与隐藏hidden
以切换样式的方式(display: none/block;
),控制元素的现实与隐藏hidden
wx:if
搭配 wx:elif
、wx:else
进行展示与隐藏的切换通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构
默认情况下,当前循环项的索引用
index
表示;当前循环项用item
表示
wx:key="index"
绑定key值。不加 {{}}
<view wx:for="{{arr}}" wx:key="index">
当前项的索引:{{index}}, 当前项:{{item}}
view>
WXSS 具有 CSS 大部分特征,同时,WXSS 还对 CSS 进行了扩充以及修改,以适应微信小程序的开发,与 CSS 相比,WXSS 扩展的特征有:
rpx 尺寸单位
rpx(responsive pixel)是微信小程序独有的,用来解决屏幕适配的尺寸单位
实现原理:
鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx 把所有设备的屏幕在宽度上等分为 750 份(即:当前屏幕的总宽度为 750 rpx)
小程序在不同设备上运行的时候,会自动把 rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
官方建议:开发微信小程序时,设计师可以使用 iPhone6 作为视觉稿的标准(1px 正好等于 2rpx)。
开发举例:在 iPhone6 上如果要绘制宽 100px,高 20px 的盒子,换算成 rpx 单位,宽高分别为 200rpx 和 40rpx。
@import 样式导入
@import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束。
/** common.wxss **/
body {
margin: 0;
padding: 0;
}
@import "common.wxss";
.box1 {
padding: 10px;
}
app.wxss
文件中定义的样式为全局样式,作用于每一个页面。.wxss
文件中定义的样式为局部样式,只作用于当前页面。注意:
- 当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式。
- 当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式。
小程序根目录下的 app.json
文件时小程序的全局配置文件。常用的配置项如下:
设置导航栏的标题
设置步骤:app.json -> window -> navigationBarTitleText
设置导航栏的背景色
设置步骤:app.json -> window -> navigationBarBackgroundColor
设置导航栏的标题颜色
设置步骤:app.json -> window -> navigationBarTextStyle
全局开启下拉刷新功能
概念:下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
设置步骤:app.json -> window -> 把 enablePullDownRefresh
的值设置为 true(在 app.json 中开启下拉刷新会作用于每一个页面)
设置下拉刷新时窗口的背景色
当全局开启下拉刷新功能之后,默认窗口背景颜色为白色。
设置步骤:app.json -> window -> 为 backgroundColor
指定 16 进制的颜色值(如:#efefef)
设置下拉刷新时 loading 的样式
当全局开启下拉刷新功能之后,默认窗口的 loading 样式为白色。
设置步骤:app.json -> window -> 为 backgroundTextStyle
指定 dark 值。(可选值只有 dark 和 light)
设置上拉触底的距离
概念:上拉触底是移动端的专有名词,指的是通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
设置步骤:app.json -> window -> 把 onReachBottomDistance
设置新的数值
示例
"window": {
"navigationBarBackgroundColor": "#2b4b6b",
"navigationBarTitleText": "第一个小程序",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true,
"backgroundColor": "#999",
"backgroundTextStyle": "dark",
"onReachBottomDistance": 50
}
tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换。小程序通常将其分为:
注意:
示例
"pages": [
"pages/demo01/demo01",
"pages/list/list",
],
"tabBar": {
"selectedColor": "#C00000", // tab 上的文字选中时的颜色
"list": [
{
"pagePath": "pages/demo01/demo01", // 页面路径,必须在 pages 中预先定义
"text": "demo01" // tab 上显示的文字
"iconPath": "图片路径", // 未选中时的图标路径
"selectedIconPath": "图片路径" // 选中时的图标路径
},
{
"pagePath": "pages/list/list",
"text": "demo02"
"iconPath": "图片路径",
"selectedIconPath": "图片路径"
}
]
}
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
配置步骤:
登录微信小程序管理后台 -> 开发 -> 开发设置 -> 服务器域名 -> 修改 request 合法域名
注意事项
调用微信小程序提供的
wx.request()
方法,可以发起 GET 数据请求
wx.request({
// 请求的接口地址,必须基于 https 协议
url: 'https://www.escook.cn/api/get',
// 请求方式
method: 'GET',
// 带给服务器的数据
data: {
name: 'andy',
age: 18
},
// 请求成功后的回调
success: res => {
console.log(res);
}
})
调用微信小程序提供的
wx.request()
方法,可以发起 POST 数据请求(配置 method 为 POST)
wx.request({
// 请求的接口地址,必须基于 https 协议
url: 'https://www.escook.cn/api/get',
// 请求方式
method: 'POST',
// 带给服务器的数据
data: {
name: 'jack',
age: 20
},
// 请求成功后的回调
success: res => {
console.log(res);
}
})
在页面刚加载的时候,自动请求一些初始化的数据。此时需要在页面的 onLoad 事件中调用获取数据的函数
/**
* 生命周期函数--监听页面加载(页面一加载就触发这个函数)
*/
onLoad(options) {
this.getInfo()
},
// 发送 get 请求
getInfo() {
wx.request({
url: 'https://www.escook.cn/api/get',
method: 'GET',
data: {
name: 'andy',
age: 18
},
success: res => {
console.log(res);
}
})
},
在开发过程中,如果后端程序员仅仅提供了 http 协议的接口、暂时没有提供 https 协议的接口,此时,为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启【不校验请求域名、web-view(业务域名)、TLS 版本及 HTTPS 证书】选项,跳过 request 合法域名的校验
注意:跳过 request 合法域名校验的选项,仅限在开发与调试阶段使用!
跨域问题只存在于基于浏览器的 Web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax 技术的核心是依赖于浏览器中的
XMLHttpRequest
这个对象,由于小程序的宿主环境是微信客户端,所以小程序不能叫做“发起 Ajax 请求”,而是叫做“发起网络数据请求”。
页面导航指的是页面之间的相互跳转。例如,浏览器中实现页面导航的方式有如下两种:
在页面上声明一个
导航组件
通过点击
组件实现页面跳转
导航到 tabBar 页面
tabBar 页面指的是被配置为 tabBar 的页面。在使用
组件跳转到指定的 tabBar 页面时,需要指定 url
属性和 open-type
属性,其中:
url
表示要跳转的页面的地址,必须以 / 开头
open-type
表示跳转得到方式,必须为 switchTab
<navigator url="/pages/message/message" open-type="switchTab">消息页面navigator>
导航到非 tabBar 页面
非 tabBar 页面指的是没有被配置为 tabBar 的页面。在使用
组件跳转到普通的非 tabBar 页面时,需要指定 url
属性和 open-type
属性,其中:
url
表示要跳转的页面的地址,必须以 / 开头
open-type
表示跳转得到方式,必须为 navigate
<navigator url="/pages/index/index" open-type="navigate">普通页面navigator>
注意:为了简便在导航到非 tabBar 页面时,
open-type="navigate"
属性可以省略
后退导航
如果要后退到上一页面或多级页面,则需要指定 open-type
属性和 delta
属性,其中:
open-type
的值必须是 navigateBack,表示要进行后退导航
delta
的值必须是数字,表示要后退的层级
<navigator open-type="navigateBack" delta="1">后退导航navigator>
注意:为了简便,如果只是后退到上一页面,则可以省略
delta
属性,因为其默认值就是 1
调用小程序的导航 API,实现页面的跳转
导航到 tabBar 页面
调用 wx.switchTab(Object object)
方法,可以跳转到 tabBar 页面。其中 Object 参数对象的属性列表如下:
// 页面结构
// 通过编程式导航,跳转到 message 页面
goMessage() {
wx.switchTab({
url: '/pages/message/message',
})
}
导航到非 tabBar 页面
调用 wx.navigateTo(Object object)
方法,可以跳转到非 tabBar 页面。其中 Object 参数对象的属性列表如下:
// 页面结构
// 通过编程式导航,跳转到 info 页面
goMessage() {
wx.navigateTo({
url: '/pages/info/info',
})
}
后退导航
调用 wx.navigateBack(Object object)
方法,可以返回上一页面或多级页面。其中 Object 参数对象可选的属性列表如下:
// 页面结构
// 通过编程式导航,跳转到 info 页面
goMessage() {
wx.navigateBack()
}
注意:为了简便,如果只是后退到上一页面,则可以省略
delta
属性,因为其默认值就是 1
navigate 组件的 url 属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数:
<navigator url="/pages/message/message?name=zs&age=20">消息页面navigator>
调用 wx.navigateTo(Object object)
方法跳转页面时,也可以携带参数
// 页面结构
// 通过编程式导航,跳转到 info 页面
goMessage() {
wx.navigateTo({
url: '/pages/info/info?name=zs&age=20',
})
}
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在 onLoad 事件中直接获取到
/**
* 生命周期函数--监听页面加载(页面一加载就触发这个函数)
*/
onLoad(options) {
// options 就是导航传递过来的参数对象
console.log(options)
}
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
启用下拉刷新的两种方式:
全局开启下拉刷新
在 app.json
的 window 节点中,把 enablePullDownRefresh
的值设置为 true
"window": {
"enablePullDownRefresh": true,
}
局部开启下拉刷新
在页面的 .json
配置文件中,把 enablePullDownRefresh
的值设置为 true
{
"usingComponents": {},
"enablePullDownRefresh": true
}
在实际开发中,推荐使用第二种方式,为需要的页面单独开启下拉刷新的效果
在页面的
.js
文件中,通过onPullDownRefresh()
函数即可监听当前页面的下拉刷新事件
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
console.log('触发了下拉刷新事件');
}
当处理完下拉刷新后,下拉刷新的 loading 效果会一直显示,不会主动消失,所以需要手动隐藏 loading 效果。此时,调用 wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
console.log('触发了下拉刷新事件');
// 当下拉刷新操作成功后,调用此函数,关闭下拉刷新效果
wx.stopPullDownRefresh()
}
生命周期(LIfe Cycle)是指一个对象从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。
我们可以把每个小程序运行的过程,也概括为生命周期:
在小程序中,生命周期分为两类,分别是:
其中,页面的生命周期范围较小,应用程序的生命周期范围较大,如图所示:
生命周期函数
是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行。
生命周期函数的作用
允许程序员在特定的时间点,执行某些特定的操作。例如,页面刚加载的时候,可以在 onLoad 生命周期函数中初始化页面的数据。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
在小程序中,生命周期函数分为两类,分别是:
小程序的应用生命周期函数需要在
app.js
中进行声明
// app.js
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {}
})
小程序的页面生命周期函数需要在页面的
.js
中进行声明
// pages/home/home.js
Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {}
})
页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
参数:
名称 | 类型 | 说明 |
---|---|---|
query | Object | 打开当前页面路径中的参数 |
页面显示/切入前台时触发。
页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
注意:对界面内容进行设置的 API 如 wx.setNavigationBarTitle(修改页面标题),请在onReady
之后进行。详见生命周期
页面隐藏/切入后台时触发。 如 wx.navigateTo 或底部 tab
切换到其他页面,小程序切入后台等。
页面卸载时触发。如 wx.redirectTo 或 wx.navigateBack 到其他页面时。
WXS(WeiXin Script) 是小程序独有的一套脚本语言,结合
wxml
,可以构建出页面的结构
wxml
中无法调用在页面的.js
中定义的函数,但是,wxml
中可以调用wxs
中定义的函数。因此,小程序中wxs
的典型应用场景就是“过滤器”
虽然 wxs 的语法类似于 JavaScript,但是 WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致
wxs 代码可以编写在 wxml 文件中的
标签内,就像 JavaScript 代码可以编写在 html 文件中的 标签内一样。
wxml 文件中的每个
标签,必须提供 module 属性,用来指定当前 wxs 的模块名称,方便在 wxml 中访问模块中的成员
<view>{{ m1.toUpper(username) }}view>
<wxs module='m1'>
// 将文本转为大写形式 zs -> ZS
// 向外暴露一个名叫 toUpper 的方法
module.export.toUpper = function(str) {
// 将结果返回出去
return str.toUpperCase()
}
wxs>
wxs 代码还可以编写在以 .wxs
为后缀名的文件内,就像 JavaScript 代码可以编写在以 .js
为后缀名的文件中一样。
// tools.wxs 文件
// 将文本转为小写形式 ZS -> zs
function toLower(str) {
return str.toLowerCase()
}
// 将 toLower 共享出去,供外界使用
module.export = {
toLower: toLower
}
在 wxml 中引入外联的 wxs 脚本时,必须为
标签添加 module 和 src 属性,其中:
<view>{{tools.toLower(username)}}view>
<wxs src="../../utils/tools.wxs" module="tools">wxs>
为了降低 wxs 的学习成本,wxs 语言在设计时借鉴了大量 JavaScript 的语法,但是在本质上,wxs 和 JavaScript 是完全不同的两种语言!
wxs 典型的应用场景就是“过滤器”,经常配合 Mustache
语法进行使用,例如:
<view>{{tools.toLower(username)}}view>
但是,在 wxs 中定义的函数不能作为组件的事件回调函数。例如,下面的用法是错误的:
<button bindtap="tools.toLower">button>
隔离性指的是 wxs 的运行环境和其他 JavaScript 代码是隔离的。体现在如下两方面:
.js
、.json
、.wxml
和 .wxss
注意:为了保证目录结构的清晰,建议把不同的组件,存放到单独的目录中,例如:
组件的引用方式分为“局部引用”和“全局引用”
局部引用
// 在页面的 .json 文件中,引入组件
{
"usingComponents": {
"my-test": "/components/test/test"
}
}
// 在页面的 .wxml 文件中,使用组件
全局引用
// 在页面的 app.json 文件中,引入组件
{
"pages": []
"window": {}
"usingComponents": {
"my-test": "/components/test/test"
}
}
// 在页面的 .wxml 文件中,使用组件
从表面来看,组件和页面都是由
.js
、.json
、.wxml
和.wxss
这四个文件组成的。但是,组件和页面的.js
与.json
文件有明显的不同:
组件的 .json
文件中需要声明 "component": true
属性
{
"component": true
}
组件的 .js
文件中调用的是 Component()
函数
// components/test/test.js
Component({
/**
* 组件的属性列表
*/
properties: {},
/**
* 组件的初始数据
*/
data: {},
/**
* 组件的方法列表
*/
methods: {}
})
组件的事件处理函数需要定义到 methods
节点中
默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的 UI 结构。
好处:
建议:在组件和引用组件的页面中建议使用 class 选择器,不要使用id 选择器、属性选择器、标签选择器!
默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过 styleIsolation
修改组件的样式隔离选项,用法如下:
// 在组件的 .js 文件中新增如下配置
Component({
options: {
styleIsolation: 'isolated'
}
})
// 或在组件的 .json 文件中新增如下配置
{
styleIsolation: 'isolated'
}
styleIsolation
的可选值:
在小程序中,用于组件模板渲染的私有数据,需要定义到
data
节点中,示例如下:
Component({
/**
* 组件的初始数据
*/
data: {
count: 0
}
})
在小程序中,事件处理函数和自定义方法需要定义到
methods
节点中,示例如下:
Component({
/**
* 组件的方法列表
*/
methods: {
// 事件处理函数
add() {
this.setData({
count: this.data.count + 1
})
this._showCount() // 通过 this 直接调用自定义方法
},
// 自定义方法建议以 '_' 开头,以区分事件处理函数和自定义方法
_showCount() {
wx.showToast({
title: 'count的值是:' + this.data.count,
icon: 'none'
})
}
}
})
在小程序中,properties 是组件的对外属性,用来接收外界传递到组件中的数据,示例如下:
Component({
/**
* 组件的属性列表
*/
properties: {
// 第一种方式:简化定义属性的方式
max: Number
// 第二种方式:完整定义属性的方式【当需要指定属性默认值时,建议使用此方式】
max: {
type: Number, // 属性值的数据类型
value: 10 // 属性默认值【如果外界没有传递 max 的值,默认等于 10】
}
},
})
<my-test1 max="10"></my-test1>
注意:上述代码中的
max
可以通过this.properties.max
访问到。
在小程序中,
properties
属性和data
数据的用法相同,它们都是可读可写的,只不过:
data
更倾向于存储组件的私有数据properties
更倾向于存储外界传递到组件的数据Component({
methods:{
showInfo() {
console.log(this.data) // 输出结果: {count: 0, max: 10}
console.log(this.properties) // 输出结果: {count: 0, max: 10}
// 结果为 true,证明 data 数据和properties 属性在本质上是一样的、都是可读可写的
console.log(this.data === this.properties)
}
}
})
由于
data
数据和properties
属性在本质上没有任何区别,因此properties
属性的值也可以用于页面渲染,或使用setData
为properties
中的属性重新赋值,示例代码如下:
Component({
properties: {
// 定义属性
max: Number
}
methods:{
addCount() {
// 使用 setData 修改属性的值
this.setData({
max: this.properties.max + 1
})
}
}
})
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于
Vue
中的watch
侦听器。在小程序组件中,数据监听器的基本语法格式如下:
Component({
observers: {
// 可以在一个监听器中监听多个字段,中间用逗号隔开。新值的顺序就是字段声明时的顺序
'字段A, 字段B': function(字段A的新值, 字段B的新值) {
// do something
}
}
})
Component({
observers: {
// 可以在一个监听器中监听多个字段,中间用逗号隔开。新值的顺序就是字段声明时的顺序
'对象.属性A, 对象.属性B': function(属性A的新值, 属性B的新值) {
// do something
}
}
})
触发上述代码中的监听器有三种情况:
为属性 A 赋值
使用 setData
设置 this.data.对象.属性A
时触发
为属性 B 赋值
使用 setData
设置 this.data.对象.属性B
时触发
直接为对象赋值
使用 setData
设置 this.data.对象
时触发
需求:一个颜色可由 R、G、B 三个部分组成,在页面中创建一个
view
,其背景颜色动态绑定为属性fullColor
、创建三个按钮,每个按钮分别控制对象rgb
中的属性 r、g、b,使用监听器监听这三个属性的变化,动态计算出fullColor
的值,从而达到修改背景颜色的效果。
Component({
/**
* 组件的初始数据
*/
data: {
rgb: { // rgb 的颜色值对象
r: 0,
g: 0,
b: 0
},
fullColor: '0, 0, 0' // 根据 rgb 对象的三个属性,动态计算 fullColor 的值
}
})
步骤:
在页面中定义元素并绑定数据
<view class="box" style="background-color: rgb({{fullColor}});">rgb的值是:{{rgb.r}},{{rgb.g}},{{rgb.b}}view>
<view>
<text class="color" bindtap="addR">Rtext>
<text class="color" bindtap="addG">Gtext>
<text class="color" bindtap="addB">Btext>
view>
在 wxss 中美化样式
/* components/test2/test2.wxss */
.box {
width: 100%;
height: 300rpx;
text-align: center;
line-height: 300rpx;
color: #fff;
}
.color {
display: inline-block;
width: 100rpx;
height: 100rpx;
text-align: center;
line-height: 100rpx;
}
.color:nth-child(1) {
background-color: red;
}
.color:nth-child(2) {
background-color: green;
}
.color:nth-child(3) {
background-color: blue;
}
定义 button 的事件处理函数
methods: {
addR() {
// 让属性自增加 5,并且判断自增过后是否大于 255,如果是,则永远等于 255
this.setData({ // 修改 rgb 对象上 r 属性的值
'rgb.r': this.data.rgb.r + 5 > 255 ? 255 : this.data.rgb.r + 5
})
},
addG() {
this.setData({ // 修改 rgb 对象上 g 属性的值
'rgb.g': this.data.rgb.g + 5 > 255 ? 255 : this.data.rgb.g + 5
})
},
addB() {
this.setData({ // 修改 rgb 对象上 b 属性的值
'rgb.b': this.data.rgb.b + 5 > 255 ? 255 : this.data.rgb.b + 5
})
}
}
监听对象中指定属性的变化
// 监听器
observers: {
// 函数中的参数为新值
// 要监听的属性用单引号包裹
// 监听多个属性用逗号隔开
'rgb.r, rgb.g, rgb.b': function(r, g, b) {
this.setData({
// 为 data 中的 fullColor 重新赋值
fullColor: `${r}, ${g}, ${b}`
})
}
}
如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符 ** 来监听对象中所有属性的变化,示例代码如下:
// 监听器
observers: {
// 监听对象中所有属性的变化,使用通配符 **
// 只要任何一个属性发生变化都会触发监听器
'rgb.**': function(obj) {
this.setData({
fullColor: `${obj.r}, ${obj.g}, ${obj.b}`
})
}
}
小程序组件可用的全部生命周期如下表所示:
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 | 1.6.3 |
attached | 无 | 在组件实例进入页面节点树时执行 | 1.6.3 |
ready | 无 | 在组件在视图层布局完成后执行 | 1.6.3 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | 1.6.3 |
detached | 无 | 在组件实例被从页面节点树移除时执行 | 1.6.3 |
error | Object Error |
每当组件方法抛出错误时执行 | 2.4.1 |
其中,最重要的生命周期是
created
attached
detached
,包含一个组件实例生命流程的最主要时间点。
created
生命周期被触发。此时,组件数据 this.data
就是在 Component
构造器中定义的数据 data
。 此时还不能调用 setData
。 通常情况下,这个生命周期只应该用于给组件 this
添加一些自定义属性字段。attached
生命周期被触发。此时, this.data
已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行(例如发请求获取初始数据)。detached
生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached
会被触发。生命周期方法可以直接定义在 Component
构造器的第一级参数中。
自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes
字段内进行声明(这是推荐的方式,其优先级最高)。
代码示例
Component({
// 推荐用法
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
}
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
// ...
})
有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期,在 pageLifetimes
定义段中定义。其中可用的生命周期包括:
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
show | 无 | 组件所在的页面被展示时执行 | 2.2.3 |
hide | 无 | 组件所在的页面被隐藏时执行 | 2.2.3 |
resize | Object Size |
组件所在的页面尺寸变化时执行 | 2.4.0 |
代码示例
Component({
pageLifetimes: {
show: function() {
// 页面被展示
},
hide: function() {
// 页面被隐藏
},
resize: function(size) {
// 页面尺寸变化
}
}
})
在页面刚被展示的时候,生成随机的 RGB 颜色值
// pageLifetimes 节点可以访问组件所在页面的生命周期函数(只能访问三个)
pageLifetimes: {
// 页面被展示
show: function() {
// 生成随机颜色
this.setData({
rgb: {
r: Math.floor((Math.random()*256)),
g: Math.floor((Math.random()*256)),
b: Math.floor((Math.random()*256))
}
})
}
}