小程序 --- 事件、数据处理、声明周期、常用 API
1. 事件
小程序中不能通过 on 来绑定事件,需要使用 bind 方法来绑定事件,并且没有click事件,需要使用 tap 事件来代替
1. 事件绑定
**方式一: **
<view bind:tap="fnName"></view>
**方式二: **
<view bindtap="fnName"></view>
2. 函数处理
page/cate/cate.js
Page({
// 所有的函数都需要写在 Page方法 中
tapName(event){
console.log(event);
}
})
3. 事件类型
1. 点击(tap)
2. 输入(input)
4. 事件对象
1. 获取用户输入的值
Page({
tapName(event){
// 获取输入框的值
console.log(event.detail.value);
}
})
5. 阻止事件冒泡
将绑定事件的方式由 bind 改为 catch
<button type="warn" catchtap="tapName">绑定事件</button>
6. 事件传参
1. data-* 传参
通过 data-* 的方式来定义需要传递的数据
<!-- 多个参数,使用多个 data-* -->
<view data-id="1" data-name="tom" bindtap="handle">点击</view>
获取自定义数据
Page({
handle(event){
// currentTarget: 事件绑定者,也就是指: 哪个组件绑定了当前事件处理函数
console.log("事件绑定者: ",event.currentTarget.dataset.id);
// target: 事件触发者,也就是指: 哪个组件触发了当前事件处理函数
// 如果事件被冒泡过,则会有所不同
console.log("事件触发者: ",event.target.dataset.id);
}
})
**注意: **
- 如果自定义属性使用的是全小写字母写法(data-parentid),event取值时同样用全小写字母取值(parentid)
- 如果自定义属性是多个单词组成的,则单词与单词之间使用 中划线(-) 进行连接(data-parent-id),event取值时,需要使用小驼峰取值(parentId)
- 如果自定义属性是使用小驼峰写法(data-parentId),event取值时,需要使用全小写字母(parentid)
2. mark 标记传参
mark 是一种自定义属性,可以在组件上添加,用于识别具体触发事件的 target 节点,同时 mark 还可以用于承载一些自定义数据
<button type="primary" bindtap="markHandle" mark:id="2" mark:name="jany">mark 传参</button>
获取自定义数据
Page({
markHandle(event){
// 如果通过事件冒泡触发的事件,则会获取到所有节点绑定的自定义数据
console.log(event.mark.id);
}
})
2. 数据
1. 数据绑定
1. 单向数据绑定
数据能影响页面,页面不会影响数据,小程序页面中使用的数据,需要在 js 文件中的 Page() 方法中,使用 data属性来定义,在 wxml 页面中使用 Mustache 语法 -- 爽大括号{{ }} 来取值
数据声明
pages/index/index.js
Page({
// 小程序页面中使用的数据,都在这里定义
data:{
id: 1,
name:"小明",
school:{
name: "新华中学"
},
isChecked: true
}
})
数据使用
pages/index/index.wxml
{{name}}
{{school.name}}
<!-- 如果需要动态绑定一个变量,属性值也需要使用双大括号 -->
<view id="{{ id }}"></view>
<!-- 通过 isChecked 来控制 checkbox 是否被选中,需要加大括号 -->
<view>
<checkbox checked="{{ isChecked }}" /> 抽烟
</view>
<!-- 算数运算 -->
<view>{{ id + 1 }}</view>
<!-- 三元运算 -->
<view>{{ id === 1 ? "等于" : "不等于" }}</view>
<!-- 逻辑判断 -->
<view>{{ id > 1 }}</view>
<!-- 只能写表达式,不能写语句,也不能调用 js 的方法 -->
2. 双向数据绑定
在 WXML 中,普通属性的绑定是单向的,当输入框中的值发生改变时,并不会影响 data 中的 address 的值
pages/index/index.html
<view>
<label for="address">地址: </label>
<input type="text" id="address" value="{{ address }}"/>
</view>
page/index/index.js
Page({
data: {
address: "北京市"
},
})
如果想要实现双向数据绑定,只需要在属性前加上model: 即可使这个属性变为双向数据绑定
<view>
<label for="address">地址: </label>
<!-- value 属性前添加 model: 来实现双向数据绑定 -->
<input type="text" id="address" model:value="{{ address }}"/>
</view>
2. 基础数据类型操作
小程序中修改数据不推荐通过赋值来进行修改,通过赋值的方式修改数据无法改变页面的数据
而是要通过 setData() 方法来修改,更新数据,并驱动视图页面的数据更新
1. 赋值方式
Page({
data: {
num: 1
},
changeNum(){
// 赋值方式修改数据,真实数据已经更新了,但是页面数据依然未被重新加载
this.data.num += 1
console.log(this.data.num);
}
})
2. setData() 方法
Page({
data: {
num: 1
},
changeNum(){
this.setData({
// setData() 方法接收一个对象,key为需要修改数据的变量名,值为需要数据做的操作
num: this.data.num + 1
})
}
})
3. 对象操作
1. 新增属性
Page({
data: {
userInfo:{}
},
changeObj(){
// 使用 setData() 方法给对象添加属性
this.setData({
// 字符串形式的 数据路径: obj.b.c
'userInfo.id': 1,
'userInfo.name': 'Tom'
})
}
})
2. 修改属性
Page({
data: {
userInfo:{
id: 1,
name: 'Tom'
}
},
changeObj(){
// 使用 setData() 方法修改对象的属性
this.setData({
// 字符串形式的 数据路径: obj.b.c
'userInfo.id': 2,
'userInfo.name': 'Jany'
})
}
})
3. 快速修改多个属性
1. 使用展开运算符
Page({
data: {
userInfo:{
id: 1,
name: 'Tom'
}
},
changeObj(){
// 1. 使用展开运算符,复制原对象中的所以属性,后面定义的属性会自动覆盖原对象中的同名属性
const userInfo = {
...this.data.userInfo,
id:2,
name: 'Jany'
}
// 2. 调用 setData() 方法,修改对象属性
this.setData({
userInfo: userInfo
})
}
})
2. 使用 Oject.assgin() 方法
Page({
data: {
userInfo:{
id: 1,
name: 'Tom'
}
},
changeObj(){
// 1. 调用 Object.assgin() 方法,合并两个对象,将需要修改的属性,覆盖原对象中的同名属性
const newObj = Object.assign(this.data.userInfo,{
id:2,
name: 'Jany'
})
// 2. 调用 setData() 方法,将新对象更新原对象
this.setData({
userInfo: newObj
})
}
})
4. 删除属性
删除单个属性
Page({
data: {
userInfo:{
id: 1,
name: 'Tom'
}
},
changeObj(){
// 1. 删除对象中的 name属性
delete this.data.userInfo.name
// 2. 更新对象
this.setData({
userInfo: this.data.userInfo
})
}
})
删除多个属性
Page({
data: {
userInfo:{
id: 1,
name: 'Tom',
age:18
}
},
changeObj(){
// 1. 使用对象结构的方式,将想保留的属性解构到 ...res 中
const {id,name,...res} = this.data.userInfo
// 2. 更新对象
this.setData({
userInfo: res
})
}
})
5. 循环
1. 基本使用
pages/index/index.wxml
<!-- 固定的两个变量名,item和index, 循环对象时,index 是对象的 key,item 是对象的值,wx:key="" 不需要加 双大括号-->
<view wx:for="{{ people }}" wx:key="index">
<text>{{ item }} -- {{ index }}</text>
</view>
pages/index/index.js
Page({
data: {
people: {
id: 1,
name: "小明",
age: 18,
}
}
})
**2. 如果需要对默认的变量名和索引进行修改,可以使用 wx:for-item 和 wx:for-index **
<!-- 将对象的属性变量名改为key,值变量名改为value -->
<view wx:for="{{ people }}" wx:key="index" wx:for-item="value" wx:for-index="key">
<text>{{ key }} --- {{ value }}</text> >
</view>
3. 将 wx:for 用在 <block/> 标签上,以渲染一个包含多节点的结构块. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染生成标签, 只接受控制属性, <block/>标签在 wxml 中可以用于组织代码结构,支持列表渲染、条件渲染等
<block wx:for="{{ people }}" wx:key="id" wx:for-item="obj" wx:for-index="i">
<view>名字: {{ obj.name }}</view>
<view>年龄: {{ obj.age }}</view>
</block>
4. 数组操作
1. 新增元素
push() 方法新增,能更新数据,无法更新页面中的显示
Page({
data: {
list: [1,2,3]
},
changeArr(){
// push() 方法可以更新数据,但是不会更新页面中的显示
this.data.list.push(4)
}
})
1. 使用 数组的 push() 方法,并调用 setData() 方法,更新数据
Page({
data: {
list: [1,2,3]
},
changeArr(){
// 1. 调用 push() 方法,将新元素新增到数组中
this.data.list.push(4)
// 2. 调用 setData(),更新数据
this.setData({
list: this.data.list
})
}
})
2. 使用 数组的 concat() 方法,并调用 setData() 方法更新数据
Page({
data: {
list: [1,2,3]
},
changeArr(){
// 1. 调用 push() 方法,将新元素合并到数组中
const newList = this.data.list.concat(4)
// 2. 调用 setData(),更新数据
this.setData({
list: newList
})
}
})
3. 使用 ...展开运算符,将元素添加到新数组,并调用 setData() 方法更新数据*
Page({
data: {
list: [1,2,3]
},
changeArr(){
// 1. 使用 ...展开运算符,将数据连同新的元素添加到新的数组中
const newList = [...this.data.list,4]
// 2. 调用 setData(),更新数据
this.setData({
list: newList
})
}
})
2. 修改元素
数据路径方式
Page({
data: {
list: [1,2,3],
objList: [{
name: "Tom"
},{}]
},
changeArr(){
this.setData({
// 使用数据路径的方式修改数组中索引为1的元素
'list[1]': 4
// 使用数据路径的方式修改数组对象中索引为1的元素
'list[0].name': 'Jany'
})
}
})
3. 删除元素
1. 调用数组的 splice() 方法,删除元素,再调用 setData() 方法 更新数据
Page({
data: {
list: [1,2,3]
},
changeArr(){
// 删除索引为0的元素,删除1个
this.data.list.splice(0,1)
// 调用 setData() 方法,更新数据
this.setData({
list: this.data.list
})
}
})
2. 调用数组的 filter() 方法,筛选出符合条件的元素,再调用 setData() 方法 更新数据
Page({
data: {
list: [1,2,3]
},
changeArr(){
// 1. 调用 filter() 方法筛选出符合条件的元素
const newList = this.data.list.filter(item => item !== 2)
// 2. 调用 setData() 方法,更新数据
this.setData({
list: newList
})
}
})
4. 循环
1. 普通数组
pages/index/index.wxml
<!-- 循环数组时, index 是 索引, item 是元素值 -->
<view wx:for="{{ list }}" wx:key="index">{{ item }}</view>
pages/index/index.js
Page({
data: {
list: [1,2,3]
}
})
2. 数组对象
pages/index/index.wxml
<!-- 如果是使用对象中的某个属性作为key, 必须加双大括号来取值 -->
<view wx:for="{{ peopleList }}" wx:key="{{ item.id }}">
<text>{{ item.name }}</text>
<text>{{ item.age }}</text>
</view>
pages/index/index.js
Page({
data: {
peopleList: [
{
id: 1,
name: "小明",
age: 18
},
{
id: 2,
name: "小红",
age: 19
},
{
id: 3,
name: "小白",
age: 16
},
]
},
})
**3. 如果需要对默认的变量名和索引进行修改,可以使用 wx:for-item 和 wx:for-index **
<!-- 将数组中的元素变量名改为 obj, 索引变量名改为 i -->
<view wx:for="{{ objList }}" wx:key="id" wx:for-item="obj" wx:for-index="i">
<text>{{ obj.name }}</text>
<text>{{ obj.age }}</text>
<text> --- {{ i }}</text>
</view>
3. 将 wx:for 用在 <block/> 标签上,以渲染一个包含多节点的结构块. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染, 只接受控制属性, <block/>标签在 wxml 中可以用于组织代码结构,支持列表渲染、条件渲染等
<block wx:for="{{ objList }}" wx:key="id" wx:for-item="obj" wx:for-index="i">
<view>名字: {{ obj.name }}</view>
<view>年龄: {{ obj.age }}</view>
</block>
3. 条件渲染
1. 逻辑语句
通过 新增和移除标签结构 来实现的
1. wx:if 、wx:elif、wx:else
page/index/index.wxml
<view wx:if="{{ num === 1 }}">num 等于 {{ num }}</view>
<view wx:elif="{{ num === 2 }}">num 等于 {{ num }}</view>
<view wx:else>num大于2, 目前num等于 {{ num }}</view>
<button type="warn" bind:tap="updateNum">更新 num</button>
pages/index/index.js
Page({
data:{
num: 1
},
updateNum(){
this.setData({
num: this.data.num + 1
})
}
})
2. hidden 属性
通过 css的 display:none 来实现的,页面中依然存在着标签结构
pages/index/index.wxml
<view hidden="{{ !isHidden }}">如果isHidden是true,则隐藏,否则展示</view>
<button type="warn" bind:tap="updateHidden">更新 isHidden</button>
pages/index/index.js
Page({
data:{
isHidden: true
},
updateHidden(){
this.setData({
isHidden: !this.data.isHidden
})
}
})
4. 运行机制
1. 图解

2. 启动
小程序的启动分为两种情况, 一种是冷启动、一种是热启动
**冷启动: **如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动
**热启动: ** 如果用户已经打开过某小程序, 然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态
3. 挂起
小程序进入[后台状态] 一段时间(5秒)后,微信停止小程序 JS 线程运行,小程序进入[挂起状态]
当开发者使用了后台播放音乐、后台地理位置等能力时,小程序可以在后台持续运行,不会进入到[挂起状态]
4. 销毁
如果用户很久没有使用小程序(30分钟),或者系统资源紧张,小程序会被销毁,即完全终止运行
5. 更新机制
在访问小程序时,微信会将小程序代码包缓存在本地。
开发者发布了新的小程序版本以后, 微信客户端会检查本地缓存的小程序有没有新版本,并进行小程序代码包的更新。
**更新机制: **
- 启动时同步更新: 微信运行时,会定期检查最近使用的小程序是否有更新。如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序。如果用户长时间未使用小程序时,会强制同步检查版本更新
- 启动时异步更新: 在启动前没有发现更新,小程序每次 冷启动 时,都会异步检查是否有更新版本。如果发现有现版本,将会异步下载新版本的代码包,将新版本的小程序在下一次冷启动进行使用,当前访问使用的依然是本地的旧版本代码
在启动时异步更新的情况下, 如果开发者希望立刻进行版本更新,可以使用 wx.getUpdateManager API 进行处理,在有新版本时提示用户重启小程序更新新版本
app.js
App({
// 冷启动时,必然会调用这个钩子函数
onLaunch(){
// 当小程序冷启动时, 会自动向微信后台请求新版本的信息,如果有新版本,会立即进行下载
// wx.getUpdateManager() 监听下载的状态,
const updateManager = wx.getUpdateManager()
// 当新版本下载完成后,会触发 onUpdateReady() 方法中定义的回调函数
updateManager.onUpdateReady(function(){
// 提示用户是否需要重启应用,进行更新新版本
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res){
if (res.confirm){
// 强制当前小程序使用新版本,并重启当前小程序
updateManager.applyUpdate()
}
}
})
})
}
})
测试编译,版本强制更新

6. 生命周期
**应用生命周期: **应用程序进程,从创建到消亡的整个过程,也就是小程序 启动 => 运行 => 销毁 的整个过程
**小程序生命周期: ** 小程序从启动到销毁的整个过程,其中包括 页面生命周期、组件生命周期
一个小程序完成整的生命周期由 应用生命周期、页面生命周期、组件生命周期 三部分组成
1. 应用生命周期
应用生命周期函数需要再 app.js 文件的 App() 方法中进行定义
1. onLaunch()
小程序冷启动初始化完成时触发,启动的整个过程只会执行一次,如果是热启动(即由后台状态切换为前台状态时,不会触发这个钩子函数)
2. onShow()
小程序冷启动或从后台状态进入前台状态(热启动)显示页面时触发
3. onHide()
小程序从前台状态进入后台状态时触发
2. 页面生命周期
页面生命周期函数需要在 页面.js 文件的 Page() 方法中进行定义
1. onLoad()
监听页面加载时触发,每个页面只会触发一次
2. onShow()
监听页面在前台展示时触发
3. onReady()
监听页面初次渲染完成时触发,每个页面只会触发一次
4. onUnload()
如使用navigator 组件跳转页面,且open-type="redirct"即关闭当前页面(销毁当前页面)时触发
5. onHide()
如使用navigator 组件跳转页面,且open-type="navigate"即保留当前页面(隐藏当前页面)时触发
3. 组件的生命周期
组件的生命周期函数需要在 lifetimes 字段中进行声明, created(重要)、attached(重要)、ready、moved、detached(重要)
1. created()
组件实例创建完毕后触发, 一般用于给组件添加一些自定义属性,此时不能调用 setData()
Component({
lifetimes: {
created () {
this.test = "测试" // 添加自定义属性
}
}
})
2. attached()
模板解析完成,并挂载到页面时触发, 一般用于给组件写一些页面交互,可以调用 setData()
3. detached()
组件被销毁时触发
4. 细节
- tabBar 页面之间相互切换,页面不会被销毁
- 点击左上角,返回上一个页面,会销毁当前页面
5. 总结
1. 小程序冷启动, 钩子函数的执行顺序

2. 保留当前页面, 进入下一个页面, 钩子函数的执行顺序、销毁当前页面, 进入下一个页面, 钩子函数的执行顺序

3. 小程序热启动, 钩子函数的执行顺序

7. 常用 API
1. 分类
**异步API: ** 通常接收一个 object 类型的参数,如: wx.request({})
**同步API: ** 通常以 Sync 结尾,如: wx.setStorageSync()
**事件监听API: ** 通常以 on 开头,如: wx.onAppHide()
异步 API 支持 callback & Promise 两种调用方式:
- 当接口参数 Object 对象中不包含 success、fail、complete 时将默认返回 Promise
- 不分接口如 request、uploadFile 本身就有返回值,因此不支持 Promise 风格的调用方式,它们的 promisify 需要开发者自行封装
2. 发送网络请求
1. 域名配置
wx.request 请求的域名必须在微信公众平台进行配置, 如果使用 wx.request 请求未配置的域名,在控制台会有响应的报错

需要开发者平台配置服务器域名

2. 跳过域名校验

3. 代码实现
pages/index/index.wxml
<block wx:for="{{ list }}" wx:key="id">
<view>
<text>{{ item.title }}</text>
<image src="{{ item.imageUrl }}" mode=""/>
</view>
</block>
<button type="warn" bind:tap="getData">发送请求</button>
pages/index/index.js
Page({
data:{
list: []
},
getData(){
wx.request({
// 接口地址
url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
// 请求方法
method: "GET",
// 请求参数
data:{},
// 请求头
header:{},
// API 执行成功后的回调
success: (res) =>{
if (res.statusCode === 200){
this.setData({
list: res.data.data
})
}
},
// API 执行失败后的回调
fail:(err) =>{
console.log(err);
},
// 不管 API 执行是否成功,都会执行
complete: () =>{
}
})
}
})
3. 提示框
1. loading
通常配置发送网络请求来使用,用于增加用户体验
**wx.showLoading(): ** 显示 loading 提示框
**wx.hideLoading(): ** 关闭 loading 提示框
Page({
data:{
list: []
},
getData(){
// 1. 当点击按钮时,就显示 loading框
wx.showLoading({
// loading框显示的文字内容
title: '数据加载中...',
// 是否显示透明蒙层, 防止触摸穿透
// 即如果设置为true, 则在 loading框 显示的时候,其背后的页面任何地方都不可以再被点击到
mask: true
})
wx.request({
url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
method: "GET",
success: (res) =>{
if (res.statusCode === 200){
this.setData({
list: res.data.data
})
}
},
fail:(err) =>{
console.log(err);
},
complete: () =>{
// 2. 无论请求是否成功,都关闭 loading框
wx.hideLoading()
}
})
}
})
2. 模态对话框、消息提示框
**wx.showModal(): ** 显示模态对话框, 如询问用户是否退出登录等
**wx.showToast(): ** 显示消息提示框,提示用户退出登录成功等
1. 回调函数风格调用
Page({
logOut(){
wx.showModal({
title: '提示', // 提示的标题
content: '是否退出登录', // 提示的内容
complete: (res) => {
// 用户点击取消后执行的逻辑
if (res.cancel) {
// 调用消息提示框,告诉用户成功退出登录
wx.showToast({
title: '成功退出登录!',
})
}
// 用户点击确定后执行的逻辑
if (res.confirm) {
// 调用消息提示框,告诉用户成功退出登录
wx.showToast({
title: '退出登录成功',
})
}
})
}
})
2. Promise 风格调用
Page({
async logOut(){
const { cancel, confirm } = await wx.showModal({
title: '提示', // 提示的标题
content: '是否退出登录', // 提示的内容
})
// 1. 用户点击确定后执行的逻辑
if (confirm) {
// 调用消息提示框,告诉用户成功退出登录
wx.showToast({
title: '成功退出登录!',
})
} else { // 2. 用户点击取消后执行的逻辑
wx.showToast({
title: '取消删除',
icon: `error`, // 更换消息提示框的图标
duration: 2000 // 设置 2s 后消息提示框消失
})
}
}
})
4. 本地存储
在小程序中使用 API 将数据存储在用户的设备上, 以便小程序运行时和下次启动时快速的读取这些数据
如果存储对象类型的数据, 可以直接进行存储和读取, 无需使用 JSON.stringify()、JSON.parse() 进行转换
1. 同步存储
**wx.setStoragesync(): ** 新增
// 第一个参数: 本地存储中指定的key
// 第二个参数: 需要存储的数据
wx.setStorageSync("num", 1)
// 如果存储的是对象类型数据, 不需要使用 JSON.stringify() 转换成 JSON 字符串
wx.setStorageSync("obj", {name: "tome", age: 16})
**wx.getStorageSync(): ** 获取
const num = wx.getStorageSync("num")
// 如果存储的是对象类型数据, 不需要使用 JSON.parse() 转换成对象
const obj = wx.getStorageSync("obj")
**wx.removeStorageSync(): ** 删除
wx.removeStorageSync("num")
**wx.clearStorageSync(): ** 清空
wx.clearStorageSync()
2. 异步存储
**wx.setStorage(): ** 新增
// 第一个参数: 本地存储中指定的key
// 第二个参数: 需要存储的数据
wx.setStorage("num", 1)
// 如果存储的是对象类型数据, 不需要使用 JSON.stringify() 转换成 JSON 字符串
wx.setStorage("obj", {name: "tome", age: 16})
**wx.getStorage(): ** 获取
async getStorage(){
const num = await wx.setStorage("num")
console.log(num)
}
// 如果存储的是对象类型数据, 不需要使用 JSON.parse() 转换成对象
async getStorage(){
const num = await wx.setStorage("obj")
console.log(obj)
}
**wx.removeStorage(): ** 删除
wx.removeStorage("num")
**wx.clearStorage(): ** 清空
wx.clearStorage()
5. 页面跳转
**声明式导航: ** navigator 组件
**编程式导航: ** 小程序提供的 API
1. wx.navigateTo()
保留当前页面, 并跳转至应用内的 非 tabBar 页面
wx.navigateTo({
url: '/pages/list/list',
})
传递参数
wx.navigateTo({
url: '/pages/list/list?name=Tom&age=23', // 直接使用 ? 携带参数,多个参数之间使用 & 连接
})
跳转后的页面中的 onLoad(options) 方法中接收参数
pages/list/list.js
Page({
onLoad(options){
console.log(options.name)
}
})
2. wx.redirectTo()
关闭当前页面, 并跳转至应用内的 非 tabBar 页面
wx.redirectTo({
url: '/pages/list/list',
})
传递参数
wx.redirectTo({
url: '/pages/list/list?name=Tom&age=23', // 直接使用 ? 携带参数,多个参数之间使用 & 连接
})
跳转后的页面中的 onLoad(options) 方法中接收参数
pages/list/list.js
Page({
onLoad(options){
console.log(options.name)
}
})
3. wx.switchTab()
跳转至 tabBar 页面, 路径后不允许携带参数
wx.switchTab({
url: '/pages/mine/mine',
})
4. wx.reLaunch()
关闭所有页面, 并跳转到应用内的某个页面
wx.reLaunch({
url: '/pages/list/list',
})
传递参数
wx.reLaunch({
url: '/pages/list/list?name=Tom&age=23', // 直接使用 ? 携带参数,多个参数之间使用 & 连接
})
跳转后的页面中的 onLoad(options) 方法中接收参数
pages/list/list.js
Page({
onLoad(options){
console.log(options.name)
}
})
5. wx.navigateBack()
关闭当前页面, 并返回上一级页面或多级页面
// 默认返回上一级页面
wx.navigateBack()
// 返回指定层级页面
wx.navigateBack({
delta:2
})
6. 上拉加载
1. 配置
在 pages/index/index.json 文件中配置 触发上拉加载的 距离页面底部距离
{
"onReachBottomDistance": 100 // 默认是 50rpx
}
2. 事件监听
在 pages/index/index.js 文件中创建 onReachBottom() 函数 用来监听页面底部的距离是否达到配置值
Page({
data:{
numList: [1,2,3]
},
// 当页面距离底部的距离达到 json 文件中的距离时触发 onReachBottom() 函数
onReachBottom(){
// 1. 展示 loading提示框
wx.showLoading({
title: '数据加载中...',
})
// 2. 模拟网络延迟
setTimeout(() => {
const lastNum = this.data.numList[this.data.numList.length -1]
const newArr = [lastNum + 1,lastNum + 2,lastNum + 3]
this.setData({
numList: [...this.data.numList,...newArr]
})
wx.hideLoading()
},1500)
}
})
7. 下拉刷新
1. 配置
在 pages/index/index.json 文件中配置 允许下拉
{
"backgroundTextStyle": "light", // loading的样式效果 light/dark
"backgroundColor": "#777", // 窗口背景色
"enablePullDownRefresh": true // 开启下拉刷新功能
}
2. 事件监听
在 pages/index/index.js 文件中创建 onPullDownRefresh() 函数 用来监听页面下拉刷新
Page({
data:{
numList: [1,2,3]
},
// 用户下拉刷新后触发 onPullDownRefresh() 函数
onPullDownRefresh(){
this.setData({
numList: [100,200,300]
})
// 在下拉刷新后, loading 效果有可能会有不会收回的bug, 这里手动调用方法,收回loading 即可
if (this.data.numList.length === 3){
wx.stopPullDownRefresh() // 收回 loading提示框
}
}
})
8. scroll-view 组件实现上拉和下拉效果
1. 上拉加载
pages/index/index.wxml
<scroll-view
lower-threshold="100" // 触底距离, 用户上拉时距离底部100px时,触发上拉加载事件
bindscrolltolower="getMore" // 监听用户上拉的自定义事件处理函数
enable-back-to-top="true" // 点击手机的状态栏,快速回到顶部
class="scroll-y"
scroll-y>
<view wx:for="{{ numList }}" wx:key="index">{{ item }}</view>
</scroll-view>
pages/index/index.scss
.scroll-y {
height: 100vh;
background-color: #efefef;
view {
height: 600rpx;
display: flex;
justify-content: center;
align-items: center;
// 所有基数的儿子标签
&:nth-child(odd){
background-color: lightgreen;
}
// 所有偶数的儿子标签
&:nth-child(even){
background-color: lightskyblue;
}
}
}
pages/index.index.js
Page({
data:{
numList: [1,2,3]
},
// 上拉加载更多的自定义事件处理函数
getMore(){
// 1. 展示 loading框
wx.showLoading({
title: '数据加载中...',
})
// 2. 模拟网络请求
setTimeout(()=>{
const lastNum = this.data.numList[this.data.numList.length -1]
const newArr = [lastNum + 1, lastNum + 2, lastNum + 3]
this.setData({
numList: [...this.data.numList, ...newArr]
})
wx.hideLoading()
},1500)
}
})
2. 下拉刷新
pages/index/index.wxml
<scroll-view
refresher-enabled // 开启下拉刷新
refresher-background="#fff" // loading 的背景颜色
refresher-default-style="black" // laoding 的默认样式,white/black/none
refresher-triggered="{{ isTriggered }}" // 是否继续展示下拉loading框,设置为false
bindrefresherrefresh="refreshHandler" // 下拉刷新的自定义事件处理函数
class="scroll-y"
scroll-y>
<view wx:for="{{ numList }}" wx:key="index">{{ item }}</view>
</scroll-view>
pages/index/index.scss
.scroll-y {
height: 100vh;
background-color: #efefef;
view {
height: 600rpx;
display: flex;
justify-content: center;
align-items: center;
// 所有基数的儿子标签
&:nth-child(odd){
background-color: lightgreen;
}
// 所有偶数的儿子标签
&:nth-child(even){
background-color: lightskyblue;
}
}
}
pages/index.index.js
Page({
data:{
numList: [1,2,3],
isTriggered: false
},
// 上拉加载更多的自定义事件处理函数
getMore(){
// 1. 展示 loading框
wx.showLoading({
title: '数据加载中...',
})
// 2. 模拟网络请求
setTimeout(()=>{
const lastNum = this.data.numList[this.data.numList.length -1]
const newArr = [lastNum + 1, lastNum + 2, lastNum + 3]
this.setData({
numList: [...this.data.numList, ...newArr],
isTriggered: false // 数据更新后, 继续将 isTriggered 设置为false,来隐藏下拉 loading 框
})
wx.hideLoading()
},1500)
}
})

浙公网安备 33010602011771号