赞
踩
4.9 列表渲染wx:for
到目前为止,我们只将第一篇《小时候的冰棍儿与雪糕》改为了数据绑定的形式,现在来尝试把所有的文章都改为数据绑定的形式。
首先将其他两篇文章的数据提取到post.js文件中,同第一篇文章的数据组成一个数组。
代码清单 将三篇文章的数据提取的js中 post.js
Page({
data:{ },
onLoad:function(){
var postList=[{
object:{
date: "Jan 14 2017",
},
title: "小时候的冰棍和雪糕",
avatar: "/images/avatar/avatar-2.png",
postImg: "/images/post/post-4.jpg",
content: "冰棍儿和雪糕绝对不是一件东西,两者的价钱大不一样,......",
collectNum: { array: [108] },
messageNum: 43,
readingNum: 34,
},
{ object:{
date: "Jan 31 2077",
},
title: "最爱的女孩",
avatar: "/images/avatar/avatar-2.png",
postImg: "/images/post/post-5.jpg",
content: "就让往事随风就随风,心随你动.。。",
collectNum: { array: [746] },
messageNum: 43,
readingNum: 94,
},
{object:{
date: "May 14 2017",
},
title: "Eason 出新歌",
avatar: "/images/avatar/avatar-2.png",
postImg: "/images/post/post-6.jpg",
content: "如果那两字没有颤动.",
collectNum: { array: [108] },
messageNum: 48927,
readingNum: 34,
}]
this.setData({
postDataList:postList
})
}
})
程序确实提供了一个wxml组件的for循环,称为列表渲染。我们一起来看看,如何使用列表渲染来改写文章列表,先给出改写后的代码。
<view class="container">
<swiper indicator-dots='ture' autoplay='ture' interval='2000' circular='true'>
<swiper-item><image src="/images/post/post-1.jpg"></image></swiper-item>
<swiper-item><image src="/images/post/post-2.jpg"></image></swiper-item>
<swiper-item><image src="/images/post/post-3.jpg"></image></swiper-item>
</swiper>
<block wx:for="{{postDataList}}" wx:for-item="item" wx:for-index="idx">
<view class="post-container">
<view class="post-author-date">
<image src="{{item.avatar}}" ></image>
<text> {{item.object.date}}</text>
</view>
<text class="post-title">{{item.title}}</text>
<image class="post-image" src="{{item.postImg}}" mdoe="aspectFill"></image>
<text class="post-content">{{item.content}}</text>
<view class="post-like">
<image src="/images/icon/wx_app_collected.png"></image>
<text>{{item.collectNum.array[0]}}</text>
<image src="/images/icon/wx_app_message.png"></image>
<text>{{item.messageNum}}</text>
<image src="/images/icon/wx_app_view.png"></image>
<text>{{item.readingNum}}</text>
</view>
</view>
</block>
</view>
重点关注<block></block>
这对括号内的代码。标签没有实质意义,它并不是组件,所以我们称作“标签”,它仅仅是一个包装,不会在页面内被渲染,可以理解为常见编程语言里的括号,在block标签中被包裹的元素将被重复渲染。
在block标签上,放置了一个wx:for的特殊属性,它的值为{{postDataList}}。wx:for将绑定一个数组,在本示例中,这个数组就是postDataList,它对应post.js文件中setData的数组数据。
wx:for-item指定数组当前元素的变量名,我们将当前元素的变量名指定为item。
wx:for-index指定当前元素在数组中序号的变量名,我们命名为idx。当然,在本示例中,只是定义了这个wx:for-index,并没有真正地使用它。
有了item这个数组子元素后,就可以按照上一小节中改写第一篇文章时所使用的{{}}语法来填写数据绑定了。在所有的{{}}填写数据绑定变量。保存运行后,发现三篇文章都可以正常显示,但代码的总量却大大减少了。
4.10 配置单个页面的导航栏背景色
在app.json中更改全局导航栏配色,代码如下:
"window":{
"navigationBarBackgroundColor":"#4A6141"
}
更改后发现,welcome页面顶部的导航栏颜色也被更换成了新的颜色。所以,我们需要单独配置welcome页面的导航栏颜色,让它不受全局配置的影响。
全局配置是在app.json中设置,那么对单个页面的配置应该在页面的json文件中配置。在welcome.json中添加如下代码:
{
"navigationBarBlackgroundColor":"#fff2cc"
}
页面的json文件只能够配置和window相关的属性。window属性的配置项请参考3.9小节。但app.json除了可以配置window外还可以配置pages、tabBar等选项。
页面的json配置不需要像app.json那样,加上window这个对象,直接编写window下面的配置项即可。
4.11 从欢迎页面跳转到文章页面
我们现在一共编写了两个页面:welcome欢迎页面与post文章页面。来尝试将两个页面连接起来,通过点击welcome页面的“开启小程序之旅”跳转到post文章页面。
首先将welcome页面重新调整为启动页面,代码如下:
代码清单 4-27 将welcome页面设置为起始页 app.json
{
"pages":[
"pages/welcome/welcome",
"pages/post/post"
],
"window":{
"navigationBarBackgroundColor":"#4A6141"
}
}
要从welcome页面跳转到post页面,需要使用事件来响应点击“开启小程序之旅”这个动作。
什么是事件?
严肃一些的定义是:事件是视图层(wxml)到逻辑层(js)的通信方式。简单一些理解,事件可以让我们在js里处理一些用户在界面上的一些操作并对这些操作做出反馈。比如点击welcome页面“开启小程序之旅”按钮后,需要在js里调用MINA框架的API,使页面从welcome跳转到post。
要实现这样的机制,需要做两件事情: 在组件上注册事件。注册事件将告诉小程序,我们要监听哪个组件的什么事件。在本例中,需要监听“开启小程序之旅”这个组件的tap事件。
更改welcome.wxml中的代码,代码如下:
代码清单 4-28 添加Tap事件 welcome.wxml
<view class="container">
<image class="avatar" src="/images/avatar/avatar-1.png"></image>
<text class="motto">大家好,我是皮皮汪</text>
<view class='journey-container' catchtap='onTapJump'>
<text class="journey">开启小程序之旅</text>
</view>
</view>
和之前的代码相比并没有太大的改动,仅仅是在class=”journey-container”的这个view组件上添加了一个catchtap=”onTapJump”的事件绑定。事件绑定的写法同组件的写法相同。它的意思是,监听点击这个动作,当用户点击这个动作后,将执行一个onTapJump的函数,这个函数必须在页面的js中定义。下面的代码定义了tap事件的处理函数。
代码清单 4-29 添加Tap操作的事件处理函数 welcome.js
Page({
onTapJump:function(event){
wx:wx.redirectTo({
url: '../post/post',
success: function(res) {
console.log("Jump success")
},
fail: function(res) {
console.log("Jump failed")
},
complete: function(res) {
console.log("Jump complete")
},
})
}
})
4.11.2 redirectTo与navigateTo
在上一小节中,我们在onTapJump函数里调用了wx.redirectTo方法从而实现了页面跳转。小程序共提供了3个导航API,以帮助开发者实现页面跳转。
wx.redirectTo
wx.navigateTo
wx.switchTap(122100版本新增)
他们之间的区别是:redirectTo将关闭当前页面,跳转到指定页面;navigateTo将保留当前页面,跳转到指定页面;而switchTap只能用于跳转到带tabbar的页面,并关闭其他所有非tabBar页面。
switchTab页面将在后面学习tabbar选项卡时再具体介绍,本节主要来看看redirectTo和navigateTo的区别。
redirectTo和navigateTo在使用方式上完全相同,他们都接受一个Object对象作为参数。Object对象中最重要的属性是url,它将指定要跳转的页面路径。
请注意url是页面的路径,不要加上文件的扩展名(如同app.json中定义pages一样)。如果在页面路径后加上一个“.wxml”,比如将url设置为url: “../post/post.wxml”,页面无法跳转,并会报错。
Object参数还可以接收3个方法,分别是:
success 跳转页面成功时MINA框架将调用此函数。
fail 跳转页面失败时MINA框架将调用此函数。
complete 无论成功或者失败,MINA框架都将调用此函数。
具体写法可参考代码清单4-29。
将这3个方法拿出来单独列举是因为在小程序中,几乎所有异步类型的API都配备有这3个方法。比如后面要学习的操作反馈API:wx.showToast,获取用户信息API:wx.getUserInfo等。在以后的其他API学习过程中我们就不再一一列举这3个方法了。
再次保存并运行以上代码,点击跳转后,页面将跳转到post文章页面。此时我们发现没有办法再返回到welcome页面了。这就是redirectTo的特点,它将卸载welcome页面,并执行页面的onUnload事件函数。再来看看navigateTo。将代码清单4-29中的wx.redirectTo更改为wx.navigateTo。保存运行代码后将发现,navigateTo跳转到post页面后,页面左上角有一个返回按钮
所以,redirectTo将关闭当前页面并将页面卸载;而navigateTo仅仅会隐藏当前页面,还可以再次返回到被隐藏的页面。这是他们最重要的区别。
再来考虑一个问题。当navigateTo跳转到post页面后,再次从post页面返回到welcome页面时,post页面会执行onHide还是onUnload呢?答案是会执行post页面的onUnload函数(不能保证以后的版本是否还会更改,但目前的130400版本确实是会执行onUnload函数)。也就是说,当从子页面返回到父页面时,子页面会被卸载。开发者可以仿照welcome页面自行验证。
但事实上,子页面执行onUnload函数的行为是从122100版本后才更改的,在之前的版本中子页面返回到父页面并不会执行onUnload函数,造成大量的子页面残留在小程序中。这在当时给开发者带来了巨大的困扰,还好官方在后续版本中更改了这个行为。页面是否被卸载是非常重要的行为,不卸载页面将使全局性的一些行为,比如音乐播放的处理,变得非常复杂。所以,了解这些页面的生命周期对于开发者来说是很重要的,否则极易引起bug。
我们还可以再试试wx.switchTab这个方法,将welcome.js中的wx.navigateTo更改为wx.switchTab,其他保持不变,运行一下代码。
页面无法执行跳转,且Console将输出jump failed。原因之前我们解释过,switchTab只能跳转到带有tabbar选项卡的页面,而post页面并不带有选项卡,所以无法执行跳转。tabbar的配置将在后面讲到,现在开发者无须关心。
现在,我们暂时选取navigateTo作为跳转方法。
4.11.3 小程序最多只能有5层页面
当我们使用navigateTo从父页面跳转到子页面后,就形成了2个页面层级。可以继续在子页面里使用navigateTo跳转到子页面。
但小程序里强制规定,只允许有最多五层父子页面。所以请开发者注意,尽量避免多层级的交互方式。事实上,太多的子页面将严重影响用户的产品体验。建议页面最多不要超过3层。
redirectTo不存在这个问题,因为当跳转到另一个页面后,上一个页面被强制卸载掉了。
4.11.4 冒泡事件与非冒泡事件
什么是冒泡事件?
冒泡事件指某个组件上的时间被触发后,事件还会向父级元素传递;父级元素还会继续向父级的父级传递,一直到页面的顶级元素。而非冒泡事件则不会向父级元素传递事件。
在4.11.1小节中,我们使用了tap事件,监听点击或者触摸动作,而tap是一个冒泡事件。常见的冒泡事件类型还有下面几种:
touchstart 手指触摸动作开始。
touchmove 手指触摸后移动。
touchcancel 手指触摸动作被打断,如来电提醒、弹窗。
touchend 手指触摸动作结束。
tap 手指触摸后马上离开。
longtap 手指触摸后,超过350ms再离开。
相对于PC上的Web浏览器,小程序的事件并不多。需要注意的是,在wxml组件里注册事件时,不可以直接使用tap=”function”或touchmove=”function”,需要在事件名之前添加catch或者bind前缀。比如在welcome页面跳转时,我们就使用了catchtap而并没有直接使用tap。
bind和catch有什么区别?
区别在于,对于以上几个冒泡事件,catch将阻止事件继续向父节点传播,而bind不会阻止事件的传播。
基本上所有的组件都有以上这些冒泡事件。
除以上6种事件外,如无特殊申明都是非冒泡事件,非冒泡事件大多不是通用事件,而是某些组件特有的事件。如的submit事件,的input事件,的scroll事件等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。