一、案例:商品列表页
1.动态修改页面标题
在首页需要跳转的地方加入跳转地址,因为跳转的目的页面的页面名称即为跳转入口名,所以在跳转地址后携带绑定参数,参数为跳转入口的名称:
url=“/pages/goodsList/goodsList?title={{item.name}}”
<!--pages/home/home.wxml-->
<!-- 分类区域 -->
<view class="grid-wrap">
<navigator url="/pages/goodsList/goodsList?title={{item.name}}" class="grid-item" wx:for="{{gridDataList}}" wx:key="id">
<image src="{{item.imgUrl}}"></image>
<text>{{item.name}}</text>
</navigator>
</view>
应当在跳转页面初次加载完成后动态设置页面名称,所以可以在“生命周期函数–监听页面初次渲染完成”函数onReady: function (){}出使用相应API设置:
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
//动态设置标题
wx.setNavigationBarTitle({
title: this.data.title,
})
},
而在设置页面标题之前需要先接收其他页面传递过来的参数,先在data中定义变量存储参数,然后通过“生命周期函数–监听页面加载”函数onLoad: function (options) {}接收参数并赋值:
data: {
title:null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options)
this.setData({
title:options.title
})
},
// js完整代码
// pages/goodsList/goodsList.js
Page({
data: {
title:null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options)
this.setData({
title:options.title
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
//动态设置标题
wx.setNavigationBarTitle({
title: this.data.title,
})
},
})
注:可以更改编译模式,改变启动页面以达到快速编程的目的:
2.获取商品列表
(1)定义一个空数组arrGoodsList接收商品数据,定义pageName为第几页数目,limit为每页多少条数目。
/**
* 页面的初始数据
*/
data: {
title: null,
arrGoodsList: [], //全部的商品数据
pageName: 1, //第几页数据
limit: 10, //每页多少条数据
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options)
this.setData({
title: options.title
});
this.getGoodsList();// 加载页面时调用商品列表函数获取商品
},
(2)发起数据请求
//请求商品列表的数据-分页
getGoodsList(callback) {
wx.request({
url: 'http://localhost:4000/goodsList',
method: "GET",
data: {
pageNum: this.data.pageName, //必传参数
limit: this.data.limit,
},
success: (res) => {
console.log(res);
this.setData({
arrGoodsList: [...this.data.arrGoodsList, ...res.data],
})
},
})
},
3.上拉触底
(1). 当要请求的数据超过总数据条数时,就不再发起请求,并且提示用户已经浏览到底部了
(2). 节流阀,控制上一次请求完成后才允许再次发起请求
data: {
dataTotal: 0, //商品总数目
isLoading: false //节流阀 初始false表示没有正在进行网络请求
},
isLoading()函数判断是否正在请求网络,若是,则不发起新的请求,直接return。
后端应当给前端数据总数。
showToast()显示提示框,提示数据到底了。
//页面上拉触底事件的处理函数
onReachBottom: function () {
if (this.data.pageName * this.data.limit >= this.data.dataTotal) {
//提示用户 数据到底了
return wx.showToast({
title: "已经没有了",
icon: "none"
});
}
//判断有没有网络请求正在进行,有的话就直接return
if (this.data.isLoading) return;
this.setData({
pageName: this.data.pageName + 1
}); //让页码+1
this.getGoodsList(); //请求下一页数据
},
4.下拉刷新
上拉刷新:重置商品数组,重新请求第1页的数据
下拉刷新后,需要请求数据。 多个步骤:下拉窗口需要手动关闭
//下拉刷新
onPullDownRefresh() {
//重置数据
this.setData({
arrGoodsList: [],
pageName: 1,
dataTotal: 0
})
//重新请求第1页的数据
this.getGoodsList(() => {
wx.stopPullDownRefresh(); //关闭下拉窗口
});
}
注意:要设置json文件中的属性样式,才能打开下拉刷新效果:
// goodsList.json
{
"usingComponents": {},
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
二、案例(续)
确保请求完成后再关闭下拉窗口的方法:回调函数
wx.showLoading()函数和 wx.hideLoading()函数呈现出数据请求的可视化过程。(手动关闭)
//请求商品列表的数据-分页
getGoodsList(callback) {
// 设置节流阀为true
this.setData({
isLoading: true
});
wx.showLoading({
title: '数据正在加载中...',
});
wx.request({
complete: (res) => {
// 设置节流阀为false
this.setData({
isLoading: false
});
wx.hideLoading();
callback && callback(); //callback存在函数值,就调用它。不存在就不调用
}
})
},
完整代码:
<!--pages/home/home.wxml-->
<!-- <text>pages/home/home.wxml</text> -->
<!-- 轮播区域 -->
<swiper indicator-dots autoplay interval="2000" circular>
<swiper-item wx:for="{{swiperImgList}}" wx:key="id">
<image src="{{item.imgUrl}}"></image>
</swiper-item>
</swiper>
<!-- 分类区域 -->
<view class="grid-wrap">
<navigator url="/pages/goodsList/goodsList?title={{item.name}}" class="grid-item" wx:for="{{gridDataList}}" wx:key="id">
<image src="{{item.imgUrl}}"></image>
<text>{{item.name}}</text>
</navigator>
</view>
<!-- 商品区域 -->
<view class="goods-wrap">
<view class="goods-item" wx:for="{{goodsDataList}}" wx:key="id">
<image src="{{item.imgUrl}}" mode="widthFix"></image>
<text>{{item.name}}</text>
</view>
</view>
<!--pages/goodslist/goodslist.wxml-->
<view class="goods-item" wx:for="{{arrGoodsList}}" wx:key="id">
<view class="goods-image">
<image src="{{item.imgUrl}}"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{item.name}}</view>
<text class="price">¥{{item.price}}</text>
<text class="sales">¥{{item.buysNum}}+付款</text>
<text class="shop-name">{{item.shopName}}</text>
</view>
</view>
/* pages/goodslist/goodslist.wxss */
.goods-item{
display: flex;
padding: 16rpx;
}
.goods-item .goods-image image{
width: 250rpx;
height: 250rpx;
margin-right: 16rpx;
border-radius: 8rpx;
}
.goods-item .goods-info{
display: flex;
flex-direction: column;
justify-content: space-around;
}
.goods-item .goods-info .goods-name{
overflow: hidden;
height: 72rpx;
font-size: 28rpx;
text-indent: 14rpx;
line-height: 36rpx;
}
.goods-item .goods-info .price{
font-size: 32rpx;
color: #cf3030;
font-weight: bold;
}
.goods-item .goods-info .sales{
font-size: 24rpx;
color: #666;
}
.goods-item .goods-info .shop-name{
font-size: 26rpx;
color: #666;
}
// pages/goodslist/goodslist.js
Page({
/**
* 页面的初始数据
*/
data: {
title: null,
arrGoodsList: [], //全部的商品数据
pageNum: 1, //第几页数据
limit: 10, //每页多少条数据
dataTotal: 0, //商品总数目
isLoading: false //节流阀 初始false表示没有正在进行网络请求
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options)
this.setData({
title: options.title
});
this.getGoodsList();
},
//请求商品列表的数据-分页
getGoodsList(callback) {
// 设置节流阀为true
this.setData({
isLoading: true
});
wx.showLoading({
title: '数据正在加载中...',
});
wx.request({
url: 'http://localhost:4000/goodsList',
method: "GET",
data: {
pageNum: this.data.pageNum, //必传参数
limit: this.data.limit,
},
success: (res) => {
console.log(res);
this.setData({
arrGoodsList: [...this.data.arrGoodsList, ...res.data],
dataTotal: res.header["X-Total-Count"] - 0
})
},
complete: (res) => {
// 设置节流阀为false
this.setData({
isLoading: false
});
wx.hideLoading();
callback && callback(); //callback存在函数值,就调用它。不存在就不调用
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
//动态设置标题
wx.setNavigationBarTitle({
title: this.data.title
});
},
//页面上拉触底事件的处理函数
onReachBottom: function () {
if (this.data.pageNum * this.data.limit >= this.data.dataTotal) {
//提示用户 数据到底了
return wx.showToast({
title: "已经没有了",
icon: "none"
});
}
//判断有没有网络请求正在进行,有的话就直接return
if (this.data.isLoading) return;
this.setData({
pageNum: this.data.pageNum + 1
}); //让页码+1
this.getGoodsList(); //请求下一页数据
},
//下拉刷新
onPullDownRefresh() {
//重置数据
this.setData({
arrGoodsList: [],
pageNum: 1,
dataTotal: 0
})
//重新请求第1页的数据
this.getGoodsList(() => {
wx.stopPullDownRefresh(); //关闭下拉窗口
});
}
})
// goodsList.json
{
"usingComponents": {},
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
// app.json
{
"pages":[
"pages/home/home",
"pages/goodsList/goodsList",
"pages/me/me",
"pages/contact/contact"
],
"tabBar": {
"list":[{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "./images/tabBar/tab01.png",
"selectedIconPath": "./images/tabBar/tab02.png"
},
{
"pagePath": "pages/contact/contact",
"text":"联系",
"iconPath": "./images/tabBar/tab03.png",
"selectedIconPath": "./images/tabBar/tab04.png"
},
{
"pagePath": "pages/me/me",
"text":"我的",
"iconPath": "./images/tabBar/tab05.png",
"selectedIconPath": "./images/tabBar/tab06.png"
}
]
},
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
三、WXS
链接: https://developers.weixin.qq.com/miniprogram/dev/reference/wxs/
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
WXS是用来解决不能在wxml中直接调用js函数的这一问题的。
1.数据类型
number: 数值
string:字符串
boolean:布尔值
object:对象
function:函数
array : 数组
date:日期
regexp:正则
2.模块
WXS 模块:
WXS 代码可以编写在 wxml 文件中的 标签内,或以 .wxs 为后缀名的文件内。
模块:
每一个 .wxs 文件和 标签都是一个单独的模块。
每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。
一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。
.wxs 文件:
在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。
wxs内联标签使用示例:
注:module模块的属性名必须唯一,否则会出现覆盖现象。
<!--pages/home/home.wxml-->
<view>
{{test.fn1()}}
</view>
<!-- 内联wxs标签 module定义当前这个模块的名字 -->
<wxs module="test">
// 写js代码 不支持es6+语法
// 导出对象
module.exports = {
fn1: function(){
console.log("fn1");
return 999;
}
}
</wxs>
注:也可以通过下列参数传递的方法获取js中的参数值:
<!--pages/home/home.wxml-->
<view>
{{test.fn1(name)}}
</view>
<wxs module="test">
module.exports = {
fn1: function(str){
return str;
}
}
</wxs>
wxs外部文件使用示例:
在工具文件夹中新建.wxs文件:
// tools.wxs
module.exports = {
fn2:function(){
return "湖人总冠军";
}
}
在wxml文件中导入模块:
<!--pages/home/home.wxml-->
<text>{{tools.fn2()}}</text>
<wxs src="../../utils/tools.wxs" module="tools"></wxs>
注:wxs里的方法不能做成事件函数,也不能调用小程序API。在IOS上wxs运行速度比其他代码快2~20倍。
wxs应用场景:大部分都是配合{{}}来使用。