3、微信小程序第三天
1、学习目标
知识点名称 | 知识点内容 | 难度系数 | 要求程度 |
---|---|---|---|
页面导航 | 声明式导航、编程式导航、导航传参 | 3星 | 掌握 |
页面事件 | 下拉刷新、上拉触底、上拉触底案例、自定义编译模式 | 3星 | 掌握 |
生命周期 | 生命周期分类、应用生命周期、页面生命周期 | 3星 | 掌握 |
wxs学习 | 认识wxs及应用场景、掌握基础语法、掌握使用方式、注意要点 | 4星 | 了解 |
本地生活案例(列表) | 导航跳转列表并传参、获取数据,渲染数据、滚动分页、下拉刷新、wxs处理手机号 | 4星 | 掌握 |
文章目录
- 3、微信小程序第三天
- 1、学习目标
- 2、页面导航
- 2.1、认识导航
- 什么是页面导航
- 实现导航的两种方式
- 声明式导航
- 编程式导航
- 2.2、声明式导航
- 导航到 tabBar 页面
- 导航到非 tabBar 页面
- 后退导航
- 2.3、编程式导航
- 导航到 tabBar
- 导航到非 tabBar 页面
- 编程式导航 – 后退导航
- 2.4、导航传参
- 声明式传递参数
- 编程式传递参数
- 接收参数
- 3、页面事件
- 3.1、下拉刷新
- 启动下拉刷新
- 配置下拉刷新窗口的样式
- 监听页面的下拉刷新事件
- 停止下拉刷新的效果
- 3.2、上拉触底
- 监听页面的上拉触底事件
- 配置上拉触底距离
- 3.3、上拉触底案例
- 效果展示
- 思路分析
- 拓展-自定义编译模式
- 4、生命周期
- 4.1、生命周期定义
- 小程序生命周期定义
- 小程序生命周期分类
- 4.2、生命周期函数
- 两个分类说明
- 应用的生命周期
- 页面的生命周期
- 5、wxs学习
- 5.1 什么是 `wxs`
- 5.2 wxs 和 JavaScript 的关系
- 5.3 拓展: `wxs` 遵循 `CommonJS` 模块化规范
- 5.4 内嵌 wxs 脚本
- 5.5 定义外联的 wxs 脚本
- 5.6 使用外联的 wxs 脚本
- 问题
- 5.7 了解 wxs 的 4 个特点
- 问题
- 6. 案例
- 6.1 商品列表页面的效果显示
- 6.2 把项目代码加载到微信开发者工具中
- 6.3 实现导航跳转并传参
- 6.4 动态设置商品列表页面的标题内容
- 6.5 创建商铺列表页面的编译模式
- 6.6 了解 API 接口并定义需要的数据节点
- 6.7 定义 getShopList 方法获取商品列表数据
- 6.8 渲染商品店铺列表的 ui 结构并美化样式
- 6.9 展示 loading 提示效果
- 6.10 上拉触底时请求下一页数据
- 6.11 对上拉触底事件进行节流控制
- 6.12 演示并分析数据加载问题
- 6.13 介绍判断是否还有下一页数据的公式
- 6.14 根据公式判断是否还有下一页的数据
- 6.15 为商铺列表页面开启下拉刷新效果
- 6.16 实现下拉刷新的逻辑
- 6.17 解决下拉窗口效果不会自动关闭的问题
- 6.18 使用 wxs 处理手机号
2、页面导航
思考
❓ Vue 中实现导航跳转的方式有几种,分别是什么?
Vue.use(VueRouter)做了什么事情
Vue 中实现导航跳转的方式有 2 种
- 声明式导航
<router-link to="/地址"></router-link>
- 编程式导航
router.push('/地址')
2.1、认识导航
什么是页面导航
页面导航指的是页面之间的相互跳转,例如,在浏览器中实现页面导航的方式有如下两种:
a 标签
location.href
实现导航的两种方式
声明式导航
在页面上声明一个 <navigator>
导航组件通过点击 <navigator>
组件实现页面跳转,具体参见文档 【组件=>导航=>navigator】
编程式导航
调用小程序的导航 API,实现页面的跳转,具体参见文档 【api=>路由】
2.2、声明式导航
tabBar页面/非tabBar页面
导航到 tabBar 页面
tabBar 页面指的是被配置为 tabBar 的页面 在使用 <navigator>
组件跳转到指定的 tabBar 页面时,需要指定 url
属性和 open-type
属性,例如:
<navigator url="/pages/home/home" open-type="switchTab">跳转到tabBar页面</navigator>
url
表示要跳转的 页面的地址,必须以/
开头open-type
表示 跳转的方式 ,必须为switchTab
导航到非 tabBar 页面
非 tabBar 页面 指的是没有被配置为 tabBar 的页面 在使用<navigator>
组件跳转到普通的非tabBar 页面时,需要指定 url
属性和 open-type
属性,例如:
<navigator url="/pages/event/event" open-type="navigate">跳转到 非tabBar页面</navigator>
url
表示要跳转的 页面的地址,必须以/
开头open-type
表示 跳转的方式 ,必须为navigate
后退导航
如果要后退到上一页面或多级页面,则需要指定 open-type
属性和 delta
属性,例如:
<navigator open-type="navigateBack">后退导航</navigator>
open-type
的值必须是navigateBack
,表示要进行后退导航delta
的值必须是数字,表示要后退的层级- 后退导航不用配置
url
- 后退导航在
tabBar
页面是无效的
2.3、编程式导航
导航到 tabBar
调用wx.switchTab({...})
方法,可以跳转到 tabBar 页面,其中 Object 参数对象的属性列表如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的 tabBar 页面的路径 ,路径后不能带参数。 |
success | function | 否 | tab跳转成功的回调函数 |
fail | function | 否 | tab跳转失败的回调函数 |
complete | function | 否 | tab跳转结束的回调函数(调用成功、失败都会执行) |
编程式导航到 tabBar
页面示例如下:
<!--页面wxml文件中-->
<button bindtap="tabFn">跳转到tabBar页面</button>
// 页面js文件中
tabFn(){
wx.switchTab({
url: "/pages/home/home"
})
}
导航到非 tabBar 页面
调用wx.navigateTo({...})
方法,可以跳转到非 tabBar 的页面。其中 Object 参数对象的属性列表如下
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的应用内非tabBar 的页面的路径, 路径后可以带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
编程式导航到非 tabBar
页面示例如下:
<!--页面wxml文件中-->
<button bindtap="tabFun">跳转到非 tabBar页面</button>
// 页面js文件中
tabFun(){
wx.navigateTo({
url:"/pages/event/event"
})
}
编程式导航 – 后退导航
调用wx.navigateBack({ ... })
方法,可以返回上一页面或多级页面。其中 Object 参数对象可选的属性列 表如下:
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
delta | number | 1 | 否 | 返回的页面数,如果delta 大于现有页面数,则返回到首页。 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
编程式导航实现后退导航示例如下:
<!--页面wxml文件中-->
<button bindtap="backFn">跳转到非 tabBar页面</button>
// 页面js文件中
backFn(){
wx.navigateBack({
delta: 1
})
}
总结:
编程式导航跳转
- tabBar界面
wx.switchTab({ url: '' })
- 非tabBar界面
wx.navigateTo({ url: '' })
- 后退导航
wx.navigateBack({ delta: 1 })
2.4、导航传参
声明式传递参数
navigator
组件的url
属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数,示例如下:
<navigator url="/pages/event/event?id=10&tom=1" >跳转到非 tabBar页面</navigator>
- 参数 与 路径 之间使用
?
分隔 - 参数键 与 参数值 用
=
相连 - 不同参数 用
&
分隔 - 注意:不能够往
tabBar
页面传递参数
编程式传递参数
调用 wx.navigateTo({ ... })
方法跳转页面时,也可以携带参数,代码示例如下:
<!--页面wxml文件中-->
<button bindtap="tabFun">跳转到非 tabBar页面</button>
// 页面js文件中
tabFun(){
wx.navigateTo({
url:"/pages/event/event?id=10&tom=1"
})
}
- 注意:不能够往
tabBar
页面传递参数
【总结】小程序里面页面传参依靠的是URL上面的查询参数,但是不能给tabBar页面传递
接收参数
通过 声明式导航传参 或 编程式导航传参 所写携带的参数,可以直接在 onLoad 事件中直接获取到,示例代码如下
// 页面的js文件中
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options) // options 就是页面传递过来的参数
}
总结概况
❓ 小程序中实现导航跳转的方式有几种,分别是什么?
- 小程序 中实现导航跳转的方式有 2 种
- 声明式导航(
<navigator url="...">
)和编程式导航 (小程序 API)
总结概况
❓ 小程序中如何实现导航传参以及如何获取参数?
- url 路径的后面携带参数,形如:
key=value&key2=value2
- onLoad 事件中使用形参 options 直接获取到
3、页面事件
3.1、下拉刷新
思考
❓ 什么是下拉刷新
下拉刷新 是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而 重新加载页面数据 的行为
启动下拉刷新
启动下拉刷新的三种方式,分别是:
-
全局开启下拉刷新
在
app.json
的window
节点中,将enablePullDownRefresh
设置为true
-
局部开启下拉刷新
在页面的
.json
配置文件中,将enablePullDownRefresh
设置为true
-
使用小程序提供的 API 实现下拉刷新
wx.startPullDownRefresh() // 主动触发下拉刷新,就像手指下拉一样的效果
注意: pc模拟器里面是无效的,手机真机是可以实现该效果
配置下拉刷新窗口的样式
在全局或页面的.json
配置文件中,通过backgroundColor
和backgroundTextStyle
来配置下拉刷新窗口的样 式,其中
backgroundColor
用来配置 下拉刷新 窗口的背景颜色,仅支持 16 进制的颜色值backgroundTextStyle
用来配置 下拉刷新loading
的样式,仅支持dark
和light
{
"usingComponents": {},
"enablePullDownRefresh": true, // 页面开启下拉刷新
"backgroundColor":"#ff0000", // 背景色
"backgroundTextStyle":'light' // loading 样式
}
监听页面的下拉刷新事件
在页面的 .js
文件中,通过 onPullDownRefresh()
函数即可监听当前页面的下拉刷新事件
Page({
/**
* 页面的初始数据
*/
data: {
count:1
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
// 用户下拉后,将count的值设置为0
this.setData({
count:0
})
},
})
停止下拉刷新的效果
当处理完下拉刷新后,下拉刷新的loading
效果会一直显示,不会主动消失, 所以需要手动隐藏loading
效果, 此时,调用 wx.stopPullDownRefresh()
可以停止当前页面的上拉刷新
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
// 用户下拉后,将count的值设置为0
this.setData({
count:0
})
// 关闭下拉刷新
wx.stopPullDownRefresh()
}
3.2、上拉触底
思考
❓ 什么是上拉触底
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为
监听页面的上拉触底事件
在页面的.js
文件中,通过onReachBottom
函数即可监听当前页面上的上拉触底事件
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log('上拉触底喽')
},
配置上拉触底距离
- 上拉触底距离指的是 触发上拉触底事件时,滚动条距离页面底部的距离
- 可以在全局或页面的
.json
配置文件中,通过onReachBottomDistance
属性来配置上拉触底的距离 - 小程序默认的触底距离是
50px
,在实际开发中,可以根据自己的需求修改这个默认值
{
"usingComponents": {},
"enablePullDownRefresh": true,
"backgroundColor":"#ff0000",
"onReachBottomDistance":100 // 距离底部还有100就触发
}
总结概况
❓ 小程序中如何监听下拉刷新以及上拉触底加载
在页面的
.js
文件中使用onPullDownRefresh()
函数 和onReachBottom()
函数
3.3、上拉触底案例
效果展示
思路分析
请求数据的过程当中需要展示loading效果,数据获取到以后,loading消失
- 定义生成随机颜色方法
- 调用获取随机颜色方法获取数据,追加到列表
- 实现加载中效果,关闭加载中
- 布局
wxml
结构,渲染数据,美化UI
样式结构 - 滚动到底获取更多数据
- 节流阀控制
实现步骤
-
获取自定义颜色的方法
getColors() { this.setData({ isloding: true }) // 需要展示 loading 效果 wx.showLoading({ title: '数据加载中...', }) wx.request({ url: 'https://www.escook.cn/api/color', method: 'get', success: ({ data: res }) => { this.setData({ colorList: [...this.data.colorList, ...res.data] }) }, complete: () => { wx.hideLoading() this.setData({ isloding: false }) } }) },
-
定义模板内容
<view> <view class="item" wx:for="{{ colorList }}" style="background-color: rgb({{ item }});"> {{ item }} </view> </view>
-
样式
/* pages/color/color.wxss */ .item { /* width: 100%; */ height: 350rpx; color: white; line-height: 350rpx; text-align: center; border-radius: 20rpx; margin: 20rpx; }
拓展-自定义编译模式
思考
❓ 现实生活中什么是生命周期?
生命周期 (Life Cycle) 是指一个对象从 创建 -> 运行 -> 销毁 的整个阶段,强调的是一个时间段,例如:
- 张三出生,表示这个人的生命周期开始
- 张三离世,表示这个人的生命周期结束
- 张三一生,就是张三的生命周期
4、生命周期
4.1、生命周期定义
小程序生命周期定义
- 小程序的 启动,表示 生命周期的开始
- 小程序的 关闭,表示 生命周期的结束
- 中间小程序运行的过程,就是小程序的生命周期
小程序生命周期分类
- 应用生命周期 特指小程序从启动 --> 运行 --> 销毁的过程
- 页面生命周期 特指小程序中,每个页面的加载 --> 渲染 --> 销毁的过程
- 小程序的生命周期图解
4.2、生命周期函数
- 生命周期函数:小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行
- 生命周期函数的作用
- 允许程序员在特定的生命周期时间点上,执行某些特定的操作
- 例如:页面刚加载的时候,在生命周期函数中自动发起数据请求,获取当前页面的数据
- 注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
两个分类说明
小程序中的生命周期函数分为两类,分别是:
- 应用生命周期函数
- 特指小程序从启动 --> 运行 --> 销毁期间依次调用的那些函数
- 页面生命周期函数
- 特指小程序中,每个页面从 加载 --> 渲染 --> 销毁期间依次调用的那些函数
应用的生命周期
应用的生命周期app.js 是小程序执行的入口文件,在 app.js 中必须调用 App() 函数,且只能调用一次。其中,App() 函数是用 来注册并执行小程序的App(Object) 函数接收一个 Object 参数,可以通过这个Object 参数,指定小程序的应用生命周期函数
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) { },
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {}
})
页面的生命周期
- 每个小程序页面,必须拥有自己的 .js 文件,且必须调用 Page() 函数,否则报错。其中 Page() 函数用来注册小 程序页
- Page(Object) 函数接收一个 Object 参数,可以通过这个 Object 参数,指定页面的生命周期函数
// pages/list/list.js
Page({
...
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log('onLoad');
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
console.log('onReady');
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
console.log('onShow');
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
console.log('onHide');
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
console.log('onUnload');
},
...
})
总结概况
❓ 小程序生命周期包含几类,分别是什么 ?
- 小程序中的生命周期,分为 2 类
- 分别是 应用生命周期 和 页面生命周期,其中应用生命周期包裹这页面生命周期
5、wxs学习
5.1 什么是 wxs
- 什么是
wxs
WXS (WeiXin Script)
是小程序的一套脚本语言,结合WXML
,可以构建出页面的结构
wxs
的应用场景wxml
中无法调用在页面的.js
中定义的函数,但是 ,wxml
中可以调用wxs
中定义的函数,因此,小程序中wxs
的典型应用场景
就是过滤器
5.2 wxs 和 JavaScript 的关系
- 虽然
wxs
的语法类似于JavaScript
,但是wxs
和JavaScript
是完全不同的两种语言wxs
有自己的数据类型number
数值类型string
字符串类型boolean
布尔类型object
对象类型function
函数类型array
数组类型date
日期类型regexp
正则
wxs
不支持类似于ES6
及以上的语法形式wxs
遵循CommonJS
规范module
对象:module.export
require
函数
5.3 拓展: wxs
遵循 CommonJS
模块化规范
CommonJS
是javascript
的模块化规范之一,小程序的脚本语言wxs
遵循了CommonJS
规范,因此,使用wxs
时的体验和使用node.js
的体验比较相似。
module
对象- 每个
wxs
都是独立的模块,每个模块均有一个内置的 module 对象,每个模块都有自己独立的作用域。
- 每个
module.exports
- 由于
wxs
拥有独立作用域,所以在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见, - 通过
module.exports
属性,可以对外共享本模块的私有变量与函数。
- 由于
- require函数
- 在
wxs
模块中引用其他wxs
文件模块,可以使用require
函数。
- 在
5.4 内嵌 wxs 脚本
-
使用的规则
wxs
代码可以编写在wxml
文件中的<wxs></wxs>
标签内,就像javascript
代码可以编写在html
文件中的<script></script>
标签内一样。wxml
文件中的每个<wxs></wxs>
标签,必须提供一个module
属性,用来指定当前<wxs></wxs>
标签的模块名。在单个wxml
文件内,建议其值唯一。- module 属性值的命名必须符合下面两个规则:
- 首字符必须是:字母(a-z A-Z),下划线(_)
- 剩余字符可以是:字母(a-z A-Z),下划线(_), 数字(0-9)
-
案例代码
5.5 定义外联的 wxs 脚本
- 使用的规则
wxs
代码可以编写在以.wxs
为后缀名的文件内,就像javascript
代码可以编写在以.js
为后缀名文件中一样。
- 实例代码
5.6 使用外联的 wxs 脚本
问题
- 引入外联wxs脚本需要src指定什么路径?
- 在
wxml
中如果要引入外联的wxs
脚本,必须为<wxs></wxs>
标签添加module
和src
属性modu le
用来为<wxs></wxs>
标签指定模块名,作为当前页面访问这个模块的标识名称src
用来指定当前<wxs></wxs>
标签要引入的脚本路径,必须是相对路径!!!
- 示例代码
5.7 了解 wxs 的 4 个特点
问题
- wxs有哪些特点?
-
没有兼容性
wxs
不依赖于运行时的基础库版本,可以在所有版本的小程序中运行 -
与
javascript
不同- 为了降低
wxs
的学习成本,wxs
语言在设计时大量借鉴了JavaScript
语法 - 但本质上,
wxs
与javascript
是不同的语言,有自己的语法,并不和javascript
一致
- 为了降低
-
隔离性
wxs
的运行环境和其他javascript
代码是隔离的wxs
中不能调用其他javascript
文件中定义的函数- 也不能调用小程序提供的
API
-
不能作为事件回调
wxs
典型的应用场景就是过滤器
,经常配置Mustache
语法进行使用
-
wxs
函数不能作为组件的事件回调
-
性能好
iOS
设备上比javascript
运行快由于运行环境的差异,在
iOS
设备上小程序内的wxs
会比javascript
代码快 2 ~ 20 倍。在
android
设备上二者运行效率无差异
6. 案例
6.1 商品列表页面的效果显示
- 页面导航并传参
- 上拉触底时加载下一页数据
- 下拉刷新列表数据
6.2 把项目代码加载到微信开发者工具中
打开微信开发者工具 --> 点击 项目
--> 导入项目
--> 选择项目目录
--> 如有必要,需要替换 AppID
6.3 实现导航跳转并传参
-
创建页面路径
pages/shoplist/shoplist
-
将九宫格的容器组件
view
改成 导航组件navigator
组件,并绑定跳转的Id
<view class="grid-list"> <navigator url="/pages/shoplist/shoplist?id={{ item.id }}&title={{ item.name }}" class="grid-item" wx:for="{{ gridList }}" wx:key="id"> <image src="{{ item.icon }}"></image> <text>{{ item.name }}</text> </navigator> </view>
6.4 动态设置商品列表页面的标题内容
-
在
onReady()
生命周期函数中对标题栏进行赋值/** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { wx.setNavigationBarTitle({ title: 'test' }) }
-
在
onLoad()
生命周期函数中获取到商品列表传递的参数/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { console.log(options) }
-
将
options
中的数据赋值给data
中的数据data: { query: {} }
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.setData({ query: options }) }
-
在
onReady()
生命周期函数中对标题栏进行赋值/** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { wx.setNavigationBarTitle({ title: this.data.query.title }) }
6.5 创建商铺列表页面的编译模式
6.6 了解 API 接口并定义需要的数据节点
以分页的形式,加载指定分类下商铺列表的数据:
-
接口地址
- https://www.escook.cn/categories/:cate_id/shops
URL
地址中的:cate_id
是动态参数,表示分类的Id
-
请求方式
GET
请求
-
请求参数
_page
表示请求第几页的数据_limit
表示每页请求几条数据
-
案例代码
data: { query: {}, shoplist: [], // 商铺列表数组 page: 1, // 页码 pagesize: 10, // 每页请求的数量 total: 0 // 总条数 }
6.7 定义 getShopList 方法获取商品列表数据
-
定义获取商品数据的方法,并将数据赋值给
data
中的shoplist
以及total
getShopList() { wx.request({ url: `https://www.escook.cn/categories/${this.data.query.id}/shops`, method: 'GET', data: { _page: this.data.page, _limit: this.data.pagesize }, success: (res) => { this.setData({ shoplist: [...this.data.shoplist, ...res.data], total: res.header['X-Total-Count'] - 0 }) } }) }
-
在
onLoad
钩子函数中,调用getShopList
方法/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.setData({ query: options }) this.getShopList() }
6.8 渲染商品店铺列表的 ui 结构并美化样式
<!-- 循环遍历生成商铺列表 -->
<view wx:for="{{shoplist}}" wx:key="id" class="shop-item">
<view class="thumb">
<image src="{{item.images[0]}}"></image>
</view>
<view class="info">
<text class="shop-title">{{item.name}}</text>
<!-- 使用wxs 中的方法, 处理手机号码 -->
<text>电话: {{item.phone}}</text>
<text>地址: {{item.address}}</text>
<text>营业时间: {{item.businessHours}}</text>
</view>
</view>
/* pages/shoplist/shoplist.wxss */
.shop-item {
display: flex;
padding: 15rpx;
border: 1rpx solid #efefef;
border-radius: 8rpx;
margin: 15rpx;
box-shadow: 1rpx 1rpx 15rpx #ddd;
}
.thumb image {
width: 250rpx;
height: 250rpx;
display: block;
margin-right: 15rpx;
}
.info {
display: flex;
flex-direction: column;
justify-content: space-around;
font-size: 24rpx;
}
.shop-title {
font-weight: bold;
}
6.9 展示 loading 提示效果
-
在网络请求发起之前调用
wx.showLoading
方法,显示loading
效果wx.showLoading({ title: '数据加载中...', })
-
在网络请求返回以后,隐藏
loading
显示complete: () => { wx.hideLoading() }
-
完整代码
getShopList() { wx.showLoading({ title: '数据加载中...', }) wx.request({ url: `https://www.escook.cn/categories/${this.data.query.id}/shops`, method: 'GET', data: { _page: this.data.page, _limit: this.data.pagesize }, success: (res) => { this.setData({ shoplist: [...this.data.shoplist, ...res.data], total: res.header['X-Total-Count'] - 0 }) }, complete: () => { wx.hideLoading() } }) }
6.10 上拉触底时请求下一页数据
-
配置页面触底的距离
{ "usingComponents": {}, "onReachBottomDistance": 100 }
-
在
onReachBottom
事件处理程序中处理逻辑/** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { this.setData({ page: this.data.page + 1 }) this.getShopList() }
6.11 对上拉触底事件进行节流控制
-
对上拉触底进行节流处理
-
在
data
中定义isLoading
节流阀false
表示当前没有进行任何数据请求true
表示当前正在进行数据请求
-
在
getShopList
方法中修改isLoading
节流阀的值- 在刚调用
getColors
时将节流阀设置为true
- 在网络请求的
complete
回调函数中,将节流阀重置为false
- 在刚调用
-
在
onReachBottom
中判断节流阀的值,从而对数据请求进行节流控制- 如果节流阀的值为
true
,则阻止当前请求 - 如果节流阀的职位
false
,则发起数据请求
- 如果节流阀的值为
-
-
代码实现
/** * 页面的初始数据 */ data: { isLoading: false // 控制是否显示 loading }
getShopList() { this.setData({ isLoading: true }) // coding…… wx.request({ url: `https://www.escook.cn/categories/${this.data.query.id}/shops`, // coding…… complete: () => { wx.hideLoading() this.setData({ isLoading: false }) } }) }
/** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { if (this.data.isLoading) return this.setData({ page: this.data.page + 1 }) this.getShopList() }
6.12 演示并分析数据加载问题
- 当没有数据时,依然能发起数据请求,这样就造成了带宽的浪费
- 在实际开发中,如果没有数据,不应该发起额外的数据请求
6.13 介绍判断是否还有下一页数据的公式
-
如果下面的公式成立,则证明没有下一页数据了:
-
页码值 * 每页显示多少条数据 >= 总数据条数
page
*pageSize
>=total
- 举例1:假设总共有 77 条数据,如果每页显示 10 条数据,则总共分为 8 页,其中第 8 页只有 7 条数据 - page (7)* pageSize (10) >= total(77)不成立, 所以有下一页数据 - page (8)* pageSize (10) >= total(77)成立, 所以没有下一页数据
- 举例2:假设总共有 80 条数据,如果每页显示 10 条数据,则总共分为 8 页,其中第 8 页面有 10条数据 - page (7)* pageSize (10) >= total(80)不成立, 所以有下一页数据 - page (8)* pageSize (10) >= total(80)成立, 所以没有下一页数据
-
-
方式二:
- 可以将
total
的值, 和数组的长度进行对比
- 可以将
6.14 根据公式判断是否还有下一页的数据
-
在
onReachBottom
钩子函数中判断数据是否加载完毕- 如果加载完毕,需要给用户提示没有更多的数据
onReachBottom: function () { if (this.data.page * this.data.pagesize >= this.data.total) { // 没有更多用户时候的提示 return wx.showToast({ title: '数据加载完毕!', icon: 'none' }) } if (this.data.isLoading) return this.setData({ page: this.data.page + 1 }) this.getShopList() }
6.15 为商铺列表页面开启下拉刷新效果
-
开启下拉刷新效果
{ "usingComponents": {}, "onReachBottomDistance": 100, "enablePullDownRefresh": true, "backgroundColor": "#efefef", "backgroundTextStyle": "dark" }
6.16 实现下拉刷新的逻辑
-
在
onPullDownRefresh
逻辑函数中监听用户下拉动作- 重置关键的数据
- 重新发起数据的请求
/** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { // 需要重置关键的数据 this.setData({ page: 1, shoplist: [], total: 0 }) // 重新发起数据请求 this.getShopList() }
6.17 解决下拉窗口效果不会自动关闭的问题
- 在
complete
回调函数中,调用关闭下拉刷线窗口的API
- 但是我们执行上拉加载更多的时候,是不需要执行这个方法的
- 所以我们在执行下拉,对数据重置,重新获取数据的方法中,传入回调函数
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
// 需要重置关键的数据
this.setData({
page: 1,
shoplist: [],
total: 0
})
// 重新发起数据请求
this.getShopList(() => {
wx.stopPullDownRefresh()
})
}
complete: () => {
wx.hideLoading()
this.setData({
isLoading: false
})
cb && cb()
}
6.18 使用 wxs 处理手机号
-
在
utils
目录下创建tools.wxs
文件,并创建splitPhone
方法function splitPhone(str) { if (str.length !== 11) return str var arr = str.split('') arr.splice(3, 0, '-') arr.splice(8, 0, '-') return arr.join('') } module.exports = { splitPhone: splitPhone }
-
在
shoplist.wxml
文件中导入tools.wxs
文件<wxs src="../../utils/tools.wxs" module="tools"></wxs>
-
使用封装的
splitPhone
方法<text>电话: {{tools.splitPhone(item.phone)}}</text>