微信开发入门第四章:文章列表页面

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事件等。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值