目录
1.小程序的页面配置
页面的配置设置app.json中的window配置项的内容(页面中配置项会覆盖app.json的window中相同的配置项),其属性值与5.2窗口配置一节中window的属性列表一致,并且在页面的json文件配置里无须写window这个键(但外部的花括号不能省略),示例代码如下所示:
{
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "主页",
}
上述代码将设置导航栏背景颜色为白色,标题字体颜色为黑色,文字为"主页"。
2.页面的生命周期
页面生命周期函数
页面的生命周期函数有以下几个: (1)onLoad:页面加载完调用该函数,一个页面只会调用一次。该函数的参数可以获取 wx.navigateTo 和 wx.redirectTo 及<navigator/>组件通过跳转的URL传递下来的参数。 (2)onShow:页面显示时调用该函数,每次打开页面都会调用一次。 (3)onReady:页面初次渲染完成调用该函数。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。 (4)onHide:页面隐藏时调用,当navigateTo或底部tab切换时调用该函数。 (5)onUnload:页面卸载时调用,当redirectTo或navigateBack的时候调用该函数。 (6)onPullDownRefresh:下拉刷新时调用。监听用户下拉刷新事件,需要 在app.json的window选项中开启enablePullDownRefresh。当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
页面生命周期函数测试案例
运行效果
代码说明
新建Chapter06项目与pageLifeCycle页面,在每个生命周期函数内部添加打印语句,具体JS代码如下:
//index.js页面逻辑文件
Page({
/** 页面的初始数据 */
data: {},
/** * 生命周期函数--监听页面加载 */
onLoad: function (options) {
console.log("---index页面onload---");
},
/** * 生命周期函数--监听页面初次渲染完成 */
onReady: function () {
console.log("---index页面onReady---");
},
/** * 生命周期函数--监听页面显示 */
onShow: function () {
console.log("---index页面onShow---");
},
/** * 生命周期函数--监听页面隐藏 */
onHide: function () {
console.log("---index页面onHide---");
},
/** * 生命周期函数--监听页面卸载 */
onUnload: function () {
console.log("---index页面onUnload---");
},
/** * 页面相关事件处理函数--监听用户下拉动作 */
onPullDownRefresh: function () {
console.log("---index页面onPullDownRefresh---");
},})
3.页面跳转
在小程序中,页面的跳转也称为路由,程序运行时,由一个统一的页面栈保存用户打开的页面,页面栈最多十层。根据页面栈中各页面不同的跳转情况微信提供了不同的路由函数,详情如表所示。
navigateTo跳转
属性说明:wx.navigateTo是使用较多的路由API函数,即保留当前页面跳转,在新页面还可以通过wx.navigateBack返回。函数具体参数说明如表所示。
JS跳转代码 wx.navigateTo函数的示例代码如下所示:
wx.navigateTo({
url: '../logs/logs', //页面url
})
页面在进行跳转时由页面栈进行统一管理。使用wx.navigateTo从页面1跳转到页面2时,页面1并不会卸载(onUnload),而是执行onHide函数。页面2入栈,执行新页面加载时的onLoad、onShow、onReady三个生命周期函数。页面生命周期函数与项目的生命周期函数在切换前后台时独立执行,互不影响。
navigator组件说明
除了在JS中编写事件处理函数,再利用wx.navigateTo函数跳转以外,还有一个与之功能相同的方法是利用navigator导航组件。组件编写在wxml视图文件中,如下面代码所示:
<!--index.wxml文件-->
<navigator url="../../pages/demo6-2/page1/page1" hover-class="none">
</navigator>
redirectTo跳转
除了用wx.navigateTo函数进行跳转以外,常用的页面跳转函数还有wx.redirectTo。与navigateTo不同,redirect是指重定向,它会直接卸载当前页面,跳转到应用内的某个页面,但是不允许跳转到 tabbar 页面。 其属性用法和wx.navigateTo类似,如下述代码所示:
wx.redirectTo({
url: '../logs/logs',
})
tabBar页面切换
在点击底部tabBar进行页面切换时,tabBar对应的每个页面都不会被卸载,而是保留当前页面直接进行切换。
页面跳转与页面生命周期案例
运行效果下面通过三个页面分别实现三种页面跳转方式。
navigateTo跳转运行效果
redirectTo跳转运行效果
redirectTo重定向跳转,会直接卸载当前页面再进行跳转,可以看到第1个页面执行onUnload生命周期函数的过程,且不能再返回原页面。使用redirectTo跳转的运行效果如图:
tabBar页面切换时生命周期测试
tabBar页面切换通常涉及3个以上的页面,页面跳转时的特性是首次加载后就不再需要重新加载,后续页面切换只执行onHide与onShow生命周期函数。使用tabBar页面切换的运行效果如图所示
案例代码说明 新建三个页面pageSwitch、page1和page2,如下加粗代码所示:
1 <!--pages/demo6-2/pageSwitch.wxml-->
<view class='container'>
<view class='page-body'>
<text class='h1'>页面跳转与页面生命周期案例</text>
<view class='demo-box'>
<view class="title">1、navigateTo导航跳转</view>
<button type="primary" bindtap="navagateToPage1">跳转到page1</button>
<!-- 第二种方式:使用navigator组件 -->
<navigator url="../../pages/demo6-2/page1/page1" hover-class="none">navigator组件跳转</navigator>
</view>
<view class='demo-box'>
<view class="title">2、redirectTo重定向跳转</view>
<button type="primary" bindtap="redirecToPage2">跳转到page2</button>
2 </view>
<view class='demo-box'>
<view class="title">3、tabBar页面切换</view>
<view class="content">请切换底部tabBar观察控制器输出</view>
</view>
</view>
</view>
"pages": [
"pages/demo6-2/pageSwitch",
"pages/demo6-2/page1/page1",
"pages/demo6-2/page2/page2",
"pages/demo6-1/pageLifeCycle",
"pages/index/index", ],
// pages/demo6-2/pageSwitch.js
Page({
navagateToPage1() {
wx.navigateTo({
url: './page1/page1',
})
},
redirecToPage2() {
wx.redirectTo({
url: './page2/page2',
})
},
/** * 生命周期函数--监听页面加载 */
onLoad: function(options) {
console.log("---pageSwitch页面onload---");
},
/** * 生命周期函数--监听页面初次渲染完成 */
//省略其他生命周期函数打印语句
})
上述代码还省略了app.json中tabBar的配置代码
4.页面间的参数传递
在进行页面跳转时往往伴随着页面的参数传递,根据用户在当前页面点击的条目将标志该条目的参数传递到下一个页面中,而后进行联网访问后台请求数据,页面间参数传递的详细过程如下:
跳转时都是通过页面的url路径完成的,与网络请求时类似的是,url是可以通过"key=value"的形式拼接参数的。第一个参数使用"?"与前面的路径相连接,后续的多个参数使用符号"&",形如:"../detail/detail?id=1&title=标题&content=测试内容"。跳转时url携带参数的示例代码如下:
//第1个页面
wx.redirectTo({
url: '../detail/detail?id=1', //此处的id为需要传递的参数
})
在下一个页面获取这个名为id的参数也十分简单。通过前面的代码学习可以观察到,在页面加载的生命周期函数onLoad通常有一个名为options的参数传入,其实这个参数对象就包含上个页面传入的数据,在跳转后JS代码中打印该参数对象options,如下面代码所示:
//第2个页面
Page({
onLoad: function (options) {
console.log(options)
}
})
由于navigator导航组件与wx.navigateTo函数实现的效果相同,因此导航组件的url属性也可拼接参数,如下述代码所示:
<navigator url="../detail/detail?id=1" hover-class="none">
</navigator>
5.新闻客户端案例讲解
功能描述与实现效果
新闻客户端小程序一共包含3个页面,分别是新闻首页、新闻详情、个人中心。其中新闻首页与个人中心两个页面使用底部的tabBar进行切换,而新闻详情通过首页点击某条新闻条目后,传递数据到下一个页面,再获取新闻的详情内容进行显示。案例最终实现效果如图
前期准备
新闻数据准备
由于还未学习涉及后台服务的云开发部分,因此本章的项目实战中数据仅为本地测试数据。一条新闻包括新闻标题、新闻缩略图、新闻内容、发布时间几个属性,可以按以上属性自行上网收集几条新闻,最终拼合成json数据的对象数组,以便后续使用。json数据样例如下所示:
[{
id: '264698',
title: '天猫161退货"猫腻",双11藏了哪些营销套路?',
poster: 'https://p1.pstatp.com/large/pgc-image/5a510771ed204376ba5fc0cc6f2f6150',
content: ' 北京时间11月12日凌晨,各大电商纷纷亮出了自己2019年度的11.11成绩单。其中,天猫双十一累计成交达2684亿,再创历史新高;....//省略 ',
add_date: '2019-11-13 09:53:30',
},
//注:省略其他两条新闻数据
]
上述代码中的poster属性为新闻的缩略图的网络地址,可以在浏览器中右键图片,复制图片链接得到。(图片地址可能失效,需要自行去网上复制更改)
页面的简单设计:依据功能描述,新闻客户端小程序共三个页面,分别是主页、个人中心与详情页。针对需求,设计其布局如图。
tabBar图标资源:在前端页面开发中,经常会用到很多PNG(便携式网络图形)格式的图标,这种图像的背景颜色是完全透明的,十分适合各种网页或者软件前端开发。 推荐一个免费实用的图标资源网站名为Iconfont-阿里巴巴矢量图标库,其链接如下: https://www.iconfont.cn/home/index。可以根据图标的描述性文字搜索好看的图标资源并下载,另外在下载时还可更改颜色和大小,如图
编码实战
新建项目与目录配置:新建项目News,新建3个功能页面,如app.json中的下述代码所示:
"pages": [
"pages/index/index",
"pages/newsDetail/newsDetail",
"pages/personal/personal"
],
首页轮播图功能
首页片轮播图WXML代码:首页的布局涉及顶部轮播图片需要用到swiper组件,详情可参见10.2.5一节。也可直接查看微信小程序开发文档"组件"→"视图容器"→"swiper"获取其最新内容。WXML代码如下所示:
<!--index.wxml页面文件-->
<swiper indicator-dots='true' autoplay='true' interval='2000' duration='1000'>
<block wx:for='{{swiperImages}}' wx:key='swiper{{index}}'>
<swiper-item> <image src='{{item.src}}' class='slide-image'></image>
</swiper-item>
</block>
</swiper>
首页轮播图功能数据
//index.js逻辑文件
Page({
data: {
swiperImages: [{ src: 'https://p1.pstatp.com/large/pgc-image/R69Ykdt8R3mX7V' },
{ src: 'https://p1.pstatp.com/list/190x124/pgcimage/RedcTpJGL3ejdf' },
{ src: 'https://p9.pstatp.com/large/pgc-image/Rhgid1x1U4IXrZ' } ],
}})
首页新闻条目展示功能:页面布局
新闻条目布局
新闻条目WXML代码:先用一条静态的新闻数据写入wxml布局文件测试,如以下代码所示:
<!--index.wxml页面文件-->
<view id='news-list'>
<view class='list-item'>
<image src='https://p1.pstatp.com/large/pgc-image/5a510771ed204376ba5fc0cc6f2f6150'></image>
<view class="news-text">
<text class='news-title'> 天猫161亿退货"猫腻",双11藏了哪些营销套路? </text>
<text class='news-date'>2019-11-13 09:53:30</text>
</view>
</view>
</view>
新闻条目样式文件
/* index.wxss样式文件 */
swiper {
height: 400rpx;
}
swiper image {
width: 100%;
height: 100%;}
#news-list {
min-height: 600rpx;
padding: 15rpx;}
.list-item {
display: flex;
flex-direction: row;
border-bottom: 1rpx solid gray;}
.list-item image {
width: 380rpx;
height: 150rpx;
margin: 10rpx;}
.news-title {
width: 100%;
display: block;
line-height: 60rpx;
font-size: 12pt;
font-weight: bold;}
.news-text{
margin: 10rpx;
display: flex;
flex-direction: column;}
.news-date{
font-size: 10pt;}
首页数据获取
util.js工具类逻辑代码:为了尽量模拟真实项目中数据的获取,可将新闻数据封装再utils文件夹下的utils.js文件中,并在该文件中添加对外的函数(相当于接口),再在其他页面中利用函数进行新闻数据的获取,根据业务需求编写获取全部新闻数据以及通过新闻的id获取新闻详情的函数,如下面代码所示:
// util.js工具类文件
let news = [ ];//中括号里的新闻内容即上一小节前期准备的新闻数据,此处不再重复给出
/** 获取全部新闻数据的接口,在主页进行新闻条目的显示 */
function getNewsList() {
let list = [];
for (var i = 0; i < news.length; i++) {
let list = [];
for (var i = 0; i < news.length; i++) {
let obj = {};
obj.id = news[i].id;
obj.poster = news[i].poster;
obj.add_date = news[i].add_date;
obj.title = news[i].title;
list.push(obj); }
return list; }}
/** 通过新闻的id获取新闻的详情内容 */
function getNewsDetail(newsID) {
let msg = {
code: '404',
news: {}
}
for (var i = 0; i < news.length; i++) {
if (newsID == news[i].id) { //id相同,更新新闻
msg.code = '200';
msg.news = news[i];
break;
}
}
return msg;
}
/** 模块的导出 */
module.exports = {
getNewsList,
getNewsDetail,
news
}
index.js调用utils:在index.js逻辑文件里获取全部的新闻数据,并复制给页面数据newsList,如以下代码所示:
//index.js逻辑文件
var common = require('../../utils/util.js')
var newsList = common.getNewsList();
Page({
data: {
swiperImages: [ ],//图片轮滑所用的图片url数组,不再重复给出
newsList: newsList
},
onLoad: function () {
console.log(this.data.newsList)
}
})
保存代码后可以看到控制台打印输出newsList对象,即利用utils文件里用getNewsList函数封装的不带内容的3个新闻条目,如图所示:
渲染新闻数据:接下来利用循环渲染标签将newsList对象显示到index页面上,如以下代码所示:
<!--index.wxml页面文件-->
<view id='news-list'>
<view class='list-item' wx:for='{{newsList}}' wx:for-item='news'>
<image src='{{news.poster}}'></image>
<view class="news-text">
<text class='news-title' data-newsID='{{news.id}}'>{{news.title}}</text>
<text class='news-date'>{{news.add_date}}</text>
</view>
</view>
</view>
新闻详情页面
新闻id的获取:在主页点击新闻条目后,程序要能正确跳转到对应新闻的详情页,需要用到navigateTo函数或者直接使用组件。同时要将新闻的id作为参数传递到下一个页面,这里采用简单的navigator组件实现,示例代码如下:
<!--index.wxml页面文件-->
<navigator url="../newsDetail/newsDetail?newsID={{news.id}}">
<view class="news-text">
<text class='news-title' data-newsID='{{news.id}}'>{{news.title}}</text>
<text class='news-date'>{{news.add_date}}</text>
</view>
</navigator>
点击新闻条目后可成功跳转到newsDetail(新闻详情)页面,且可在newsDetail页面的初始化生命周期函数onLoad中打印上一页面传递的参数,可看到新闻的id被成功打印,如图所示:
新闻详情页布局:有了主页布局的基础,新闻详情页的布局同样十分简单,同样先用静态数据进行页面布局调试,示例代码如下:
<!--newsDetail.wxml文件-->
<scroll-view class='container' scroll-y="true" style="height: 100%;">
<view class='title'>天猫161亿退货猫腻,双11藏了哪些营销套路?</view>
<view class='poster'>
<image src='https://p1.pstatp.com/large/pgimage/5a510771ed204376ba5fc0cc6f2f6150'>
</image>
</view>
<view class='content'>
<text space="emsp">北京时间11月12日凌晨,各大电商纷纷亮出了自己2019年度的11.11成绩单。..//省略新闻内容
</text>
</view>
<view class='add_date'>时间:2019-11-13 09:53:30</view>
</scroll-view>
保存后新闻详情页面效果如图
新闻详情页数据获取: 可通过utils里的函数获取新闻详情内容,如下述代码所示:
// pages/detail/detail.js
var common = require('../../utils/util.js')
Page({
data: { article:[] },
onLoad: function (options) {
console.log(options)
let id = options.newsID;
let result = common.getNewsDetail(id);
if (result.code == '200') {
this.setData({
article: result.news,
})
}
console.log(this.data.article)
}
})
保存后从主页进入新闻详情页时可以看到打印的新闻id和article对象,如图所示
获取到数据后直接通过双括号将新闻数据渲染到页面上,即完成了首页点击到新闻详情页面的整个功能,如下述代码所示:
<!--newsDetail.wxml文件-->
<scroll-view class='container' scroll-y="true" style="height: 100%;">
<view class='title'>{{article.title}}</view>
<view class='poster'>
<image src='{{article.poster}}'>
</image>
</view>
<view class='content'>
<text space="emsp"> {{article.content}}
</text>
</view>
<view class='add_date'>时间:{{article.add_date}}</view>
</scroll-view>
个人中心页面
头像与昵称部分WXML代码:最后一个页面是个人中心,在这里看到用户头像和昵称,还可以放置其他设置项等。在开发过程中经常会用到微信用户的一些公开信息,如头像和昵称等,可参考微信官方API文档的wx.getUserInfo函数使用。若在个人中心页面只用于显示用户头像和昵称,可以利用简单的<open-data>组件获取用户的头像以及昵称等公开信息,用法如下述代码所示:
<!--personal.wxml 文件-->
<view class="userinfo-avatar">
<open-data type="userAvatarUrl" lang="zh_CN"></open-data>
</view>
<open-data type="userNickName" lang="zh_CN"></open-data>
样式文件代码:由于头像在开发过程中经常以圆形样式展现,可以编写如下样式:
/* personal.wxss 样式文件*/
.userinfo-avatar {
overflow: hidden;
width: 200rpx;
height: 200rpx;
border-radius: 50%;
}
个人中心页面完整WXML代码:按照页面设计中个人中心页面布局编写简单的布局代码,如下所示:
<!--personal.wxml 文件-->
<view class="container">
<view class="head-img">
<view class="userinfo-avatar">
<open-data type="userAvatarUrl" lang="zh_CN"></open-data>
</view>
</view>
<view class="nickname">
<open-data type="userNickName" lang="zh_CN"></open-data>
</view>
</view>
个人中心页面完整WXSS文件
/* personal.wxss 样式文件*/
.container {
height: 500rpx;
width: 100%;
}
.userinfo-avatar {
overflow: hidden;
width: 200rpx;
height: 200rpx;
border-radius: 50%;
}
6.小结
页面配置围绕着页面的json文件进行,相较于app.json,页面的json文件较为简单只用于窗口的配置。而后围绕页面的js文件进行了页面生命周期的学习,页面生命周期在页面启动、页面跳转时尤为重要,需熟悉页面的3种切换方式,明确在不同方式跳转页面时,生命周期函数的执行过程,最后结合新闻客户端综合案例学会页面间参数的传递方式。