- 知道如何实现页面之间的导航跳转
- 知道如何实现下拉刷新效果
- 知道如何实现上拉加载更多效果
- 知道小程序中常用的生命周期钩子函数
页面导航指的是页面之间的相互跳转,例如,浏览器实现页面导航的方式有两种:
<a>
超链接location.href
- 声明式导航
- 在页面中生命一个
<navigator>
导航组件 - 通过点击
<navigator>
组件来实现页面跳转
- 在页面中生命一个
- 编程式导航
- 调用小程序导航 API
tabBar 页面指的是被配置为tabBar
的页面
在使用<navigator>
组件跳转到指定的tabBar
页面时,需要指定url
属性和open-type
属性
url
表示要跳转的页面的地址,必须以/
开头open-type
表示为跳转的方式,必须是swicthTab
<navigator url="/pages/index/index" open-type="switchTab">
跳转到 index tabBar
</navigator>
非 tabBar 页面指的是未被配置到tabBar
的页面
在使用<navigator>
组件跳转到指定的tabBar
页面时,需要指定url
属性和open-type
属性
url
表示要跳转的页面的地址,必须以/
开头open-type
表示为跳转的方式,必须是navigate
<navigator url="/pages/user/user" open-type="navigate">
跳转到 user
</navigator>
如果需要后退到上一级页面甚至多级页面,需要指定open-type
属性和delta
属性
open-type
值必须是navigateBack
,表示为后退导航delta
的值必须是数字,表示后退的级数
<navigator open-type="navigateBack" delta="3">
后退3个页面
</navigator>
调用wx.switchTab(Object object)
方法,可以跳转到 tabBar 页面,其中 Object 是参数对象,属性如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的 tabBar 的页面路径,路径不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(包括成功、失败) |
wx.switchTab({
url: '/pages/index/index',
// 如果没有特殊需求,写一个 url 即可
success: function() {
console.log('跳转成功')
},
fail: function() {
console.log('跳转失败')
},
complete: function() {
console.log('执行跳转')
}
})
调用wx.navigateTo(Object object)
方法,可以跳转到 tabBar 页面,其中 Object 是参数对象,属性如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的 tabBar 的页面路径,路径不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(包括成功、失败) |
wx.navigateTo({
url: '/pages/user/user'
})
调用wx.navigateBack(Object object)
方法,可以跳转到 tabBar 页面,其中 Object 是参数对象,属性如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
delta | number | 否 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页(默认值:1) |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(包括成功、失败) |
// 默认值是 1
wx.navigateBack()
navigator 组件中的 url 属性可以指定跳转的页面的路径,同时路径后面也可以携带一些参数:
- 参数与路径之间使用
?
分开 - 参数与参数值直接使用
=
相连 - 不同参数之间使用
&
分割
<navigator url="/pages/info/info?username=zs&age=18">
跳转到 info 页面
</navigator>
调用wx.navigateTo(Object object)
方法时,也可以携带参数
<button bindtap="goToInfo"></button>
goToInfo: function () {
wx.navigateTo({
url: '/pages/info/info?username=zs&age=18'
})
}
通过声明式导航的编程式导航进行传递的参数,可以通过在onLoad
钩子函数中获取到
onLoad: function (options) {
// options 就是导航传递过来的参数对象
console.log(options)
}
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,来重新加载页面的行为
- 全局开启下拉刷新(不推荐)
- 在
app.json
中的window
节点中,将enablePullDownRefresh
设置为true
- 在
- 局部开启下拉刷新
- 只为需要的页面单独开启下拉刷新效果
- 在页面的
.json
中将enablePullDownRefresh
设置为true
通过在页面或全局的.json
文件中,配置backgroundColor
和backgroundTextStyle
来定制不同的下拉刷新样式
backgroundColor
:配置下拉刷新的背景颜色,仅支持16禁止的颜色值backgroundTextStyle
:配置下拉刷新的loading 样式
,仅支持dark/light
{
"backgroundColor": "#00000",
"backgroundTextColor": "light"
}
通过onPullDownRefresh
来监听页面的下拉刷新事件
onPullDownRefresh: function() {
// 下拉刷新,重新获取数据
this.getDataList()
}
下拉刷新的效果不会自动关闭,我们可以在获取数据成功后让下拉刷新停止。调用wx.stopPullDownRefresh()
来关闭下拉刷新
onPullDownRefresh: function() {
// 获取数据操作......
// 获取数据成功,停止下拉刷新
wx.stopPullDownRefresh()
}
上拉触底是移动端的专有名词,指的是通过手指在屏幕上的上拉拉滑动操作,来重新加载页面的行为,一般上拉触底实现的就是分页
效果
通过onReachBottom
来监听上拉触底事件
onReachBottom: function() {
// 上拉触底,加载第二页
this.getDataList(params)
}
上拉触底距离,指的就是触发上拉触底事件后,滚动条距离页面底部的距离,默认是 50 px,我们可以在全局或页面的.json
文件中,配置onReachBottomDistance
来改变上拉触底的距离,默认是 px 作为单位,配置时不需要加入单位
{
"onReachBottomDistance": 80
}
Page({
data: {
colorList: [],
},
getColors: function(){
return Math.floor(Math.random()*255)
},
getColorList: function(){
const arr = []
for(let i=0;i<10;i++){
arr[i] = {id: i, color: [this.getColors(), this.getColors(), this.getColors()]}
}
return arr;
},
getColorListByPage: function(){
const arr = this.getColorList();
this.setData({
colorList: [...this.data.colorList, ...arr]
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getColorListByPage();
},
}
<view
wx:for="{{ colorList }}"
wx:key="{{item.id}}"
class="color-item"
style="background-color: rgba({{item.color}})"
>{{item.color}}</view>
.color-item {
border:1px solid #efefef;
line-height: 200rpx;
border-radius: 15rpx;
margin: 15rpx;
text-align: center;
text-shadow: 0rpx 0rpx 5rpx #fff;
box-shadow: 1rpx 1rpx 6rpx #aaa;
}
调用wx.showLoading(Object object)
显示加载框,调用wx.hideLoading()
隐藏加载框
getColorListByPage: function(){
wx.showLoading({
title: '加载中...',
})
new Promise((resolve) => {
setTimeout(()=> {
const arr = this.getColorList();
this.setData({
colorList: [...this.data.colorList, ...arr]
})
resolve()
},300)
}).finally(() => {
wx.hideLoading({
success: (res) => {},
})
})
},
- 在 data 中定义 isloading 节流阀
- 在获取颜色的方法中修改 isloading 节流阀的状态
- 获取颜色刚开始,将节流阀改为 true
- 获取颜色结束,将节流阀改为 false
- 在 onReachBottom 中判断节流阀的状态
- 如果节流阀是 false,才会触发请求颜色
如果我们的首页是index
,但是我们在开发user
这个Tab,每次更新都要重新点击一次,那么有方法可以更新后直接进入到user
呢?
将启动页面更改为pages/user/user
即可,还可以设置启动参数和进入场景
生命周期(Life Cycle)是指一个对象从创建 -> 运行 -> 销毁
的整个过程。强调的是一个时间段。
- 小程序启动,表示生命周期的开始
- 小程序关闭,表示生命周期的结束
- 小程序运行的过程,表示整个小程序的生命周期
在小程序中,生命周期分为两类:
- 应用生命周期
- 小程序从
启动 -> 运行 -> 销毁
的过程
- 小程序从
- 页面生命周期
- 小程序中每个页面的
加载 -> 渲染 -> 销毁
的过程
- 小程序中每个页面的
生命周期函数:由小程序框架提供的内置函数,会伴着生命周期的不同阶段自动按次序执行
生命周期函数的作用:允许程序员在特定时间执行特定操作,比如在onLoad
函数中加载页面的初始数据
注意:生命周期强调的是一个时间段,生命周期函数强调的是一个时间点
生命周期函数分为两类:
- 应用的生命周期函数
- 页面的生命周期函数
小程序的应用生命周期函数需要在app.js
中声明,示例如下:
// app.js
App({
// 小程序初始化完成执行此函数,全局仅触发一次
onLaunch: function () {},
// 小程序启动,或从后台进入前台时触发
onShow: function (options) {},
// 小程序从前台进入后台时触发
onHide: function () {},
// 小程序脚本出现错误时,或调用 API 失败时,调用此函数,并携带错误信息
onError: function (msg) {}
})
-
前台与后台:如果我们切换界面,例如按下 Home 键,此时小程序就进入后台运行
-
onLaunch
:小程序初始化触发,全局仅触发一次 -
onShow
:小程序在前台运行时触发 -
onHide
:小程序在后台运行时触发 -
onError
:小程序 JS 脚本错误,或调用 API 错误时触发
小程序的页面生命周期函数需要在Page.js
中声明,示例如下:
Page({
// 监听页面加载,一个页面只调用1次
onLoad: function (options) {},
// 监听页面初次渲染完成,一个页面只调用1次
onReady: function () {},
// 监听页面显示
onShow: function () {},
// 监听页面隐藏
onHide: function () {},
// 监听页面卸载(销毁)
onUnload: function() {}
})
onLoad
:监听页面加载,一个页面只调用1次onReady
:监听页面初次渲染完成,一个页面只调用1次onShow
:监听页面显示onHide
:监听页面隐藏onUnload
:监听页面卸载(销毁)
WXS(WeiXin Script)是小程序独有的脚本语言,结合 WXML,可以构建出页面结构
WXML 中无法调用页面中的.js
的函数,但是 WXML 可以调用 WXS 中的函数,因此小程序中的 WXS 的典型应用场景是过滤器
虽然 WXS 的语法类似于 JavaScript,但是本质上这两者是完全不同的编程语言:
- WXS 有自己的数据类型
number
数值类型,string
字符串类型,boolean
布尔类型,object
对象类型function
函数类型,array
数组类型,date
日期类型,regexp
正则类型
- WXS 不支持 ES6 及以上的高级语法
- 不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc...
- 支持:
var
声明变量,普通function
以及其他 ES5 语法
- WXS 遵循 CommonJS 的规范
module
对象require
函数module.exports
暴露成员
wxs 可以编写在 WXML 的<wxs>
标签内,类似于 JS 编写在 HTML 的<script>
每一个<wxs>
标签必须提供module
属性,用来指定当前 WXS 的模块名称,方便在 WXML 中访问成员
<view>{{ m1.toUpper('zs') }}</view>
<wxs module="m1">
module.exports.toUpper = function(str) {
return str.toUpperCase();
}
</wxs>
wxs 还可以编写在.wxs
文件内
// tool.wxs
var toLower = function (str) {
return str.toLowerCase()
}
module.exports = {
toLower: toLower
}
<!-- WXML 页面中 -->
<wxs src="./tool.wxs" module="tool"></wxs>
<view>{{ tool.toLower('LS') }}</view>
为了降低 WXS 的学习成本,WXS 在设计初借鉴了 JS 的很多语法,但是本质上,WXS 与 JS 是两门不同的编程语言!
WXS 的典型应用场景就是过滤器
,经常配合 Mustache 语法进行回调,例如
<view>{{ m1.toUpper(str) }}</view>
但是不能作为组件的事件回调,下面的语法是错误的:
<button bindinput="m1.doSomething">点击</button>
指的是 WXS 和其他 JS 代码是隔离的,体现在两个方面:
- WXS 不能调用 JS 中的函数
- WXS 不能调用小程序的 API
- 在 IOS 设备上,WXS 比 JS 的性能要快 2~20 倍
- 但是在安卓设备上,这两者没有什么差异
如果我们的某个页面是复用的,例如管理所有的用户,点击某个用户的信息,上方的navigationBarTitleText
显示的就是用户名,此时我们就不能写死了,需要在页面的生命周期函数中
Page({
onReady: function () {
wx.setNavigationBarTitle({
title: 'xx用户'
})
}
})
举个例子:
<!-- 用户列表的 WXML 页面 -->
<view>
用户名:张三
操作:<button bindtap="goToInfo" data-username="张三">详情</button>
</view>
<view>
用户名:李四
操作:<button bindtap="goToInfo" data-username="李四">详情</button>
</view>
// 用户列表页面的 .js 文件
Page({
goToInfo: function (e) {
// 编程式导航传参
wx.navigateTo({
url: '/pages/userinfo/info?username=' + e.target.dataset.username
})
}
})
// userinfo.js
Page({
data: {
username: '',
},
// onLoad 接收导航参数
onLoad: function (options) {
this.setData({
username: options.username
})
},
// onReady 更改页面标题
onReady: function () {
wx.setNavigationBarTitle({
title: this.data.username
})
}
})
判断是否还有下一页数据的公式:
页码值 * 每页条数 >= 总条数
,如果结果是true
,则没有下一页数据了
// page
Page({
data: {
pagenum: 1,
pagesize: 10,
total: 100
},
// onReachBottom 监听页面触底事件
onReachBottom: function () {
// 先判断是否有下一页
if(this.data.pagenum * this.data.pagesize >= this.data.total) {
// 如果没有下一页,不加载下一页,并提示用户
return wx.showToast({
title: "没有下一页了...",
icon: "none"
});
}
// 有下一页就加载下一页
this.setData({
pagenum: this.data.pagenum + 1
})
}
})