小程序从0到1:微信全栈工程师一本通
上QQ阅读APP看书,第一时间看更新

2.3 实现页首splash效果

本节将学习如何在小程序页首实现图2-13所示的效果。

图2-13

2.3.1 使用swiper组件

2.1.5节使用swiper组件实现了全屏的splash效果,本节将再次使用这个组件实现页面顶部的splash效果。

切换至编辑模式,在文档树中打开pages/dou-ban/index.wxml文件,修改代码为:

    <swiper  style="height:450rpx"  indicator-dots  autoplay="true"  interval="5000"
        duration="1000">
        <swiper-item wx:for="{{ boards[0].movies }}" wx:key="{{ item.id }}">
            <navigator hover-class="none">
                <image style="height:450rpx; width:750rpx; " src="{{ item.images.large }}"
                    mode="aspectFill" />
            </navigator>
        </swiper-item>
    </swiper>

这里使用的仍然是swiper组件,与2.1.5节的不同之处在于,此次设置height为450rpx。rpx是responsive pixel的简称,是小程序开发中实现屏幕自适应UI的长度单位。在页面设计上,微信小程序规定屏幕的宽恒为750 rpx。iPhone6屏幕的宽度为375px,换算过来则是1rpx=0.5px,以此设计UI元素的尺寸。其他型号的手机,1rpx所代表的宽度将视屏宽而定。

此处设置swiper高度为450rpx,比屏宽的一半略高,这也是常见的设计比例。

在文档树中打开pages/douban/index.js页面,修改data声明为:

    data: {
        boards: [{ key: 'in_theaters' }, { key: 'coming_soon' }, { key: 'top250' }],
    },

其中,“in_theaters”“coming_soon”等是豆瓣API需要用到的参数。

2.3.2 批量调用接口

在当前页面“pages/douban/index”的逻辑层代码中,我们需要调用豆瓣接口三次拉取三个不同的榜单数据。在全部拉取完成之后,再调用setData方法渲染页面。这种场景比较适合使用sim.js类库提供的app.promise.all方法批量调用接口。

批量调用接口,可采用如下方式。

添加一个retrieveData函数:

    retrieveData() {
        let app = getApp()
        var promises = this.data.boards.map(function (board) {
            return app.request(`https://api.douban.com/v2/movie/${board.key}? start=
                0&count=10`)
                .then(function (d) {
                if (! d) return board
                board.title = d.title
                board.movies = d.subjects
                return board
            }).catch(err => console.log(err))
        })
        return app.promise.all(promises).then(boards => {
            if (! boards || ! boards.length) return
            this.setData({ boards: boards, loading: false})
        })
    }

这个函数主要完成如下两件事情。

❑ 依据参数不同,从豆瓣API拉取三次列表。

❑ 待三次拉取全部完成之后,调用setData设置数据通知页面渲染。

sim.js类库中复合了bluebird类库,这是一个Promise类库,主要提供了如下四种功能。

❑ 使用then实现链式调用。

❑ 使用Promise.all实现并行调用。

❑ 使用Promise.race实现竞赛调用。

❑ 使用catch捕捉异常。

sim.js框架将Promise对象注入到了App对象上,所以在这里可以使用app.promise.all进行并行调用。它与直接使用Promise.all的效果是等同的,但免去了在Page页面中再次引用js类库的麻烦。关于Promise,稍后会有更多的介绍。

代码中出现的then的用法,在2.1.5节已经讲过,它表示异步调用成功之后应执行什么。

2.3.3 使用wx.getStorage接口

在2.1.5节,笔者在“pages/douban/splash”页面向本地缓存中存入了“has_shown_splash”变量,用于标识已经进入过splash页面。本节将尝试取出这个变量,如果不为空,则调用“retrieveData”函数;如果为空,则跳转至“pages/douban/splash”页面。

在onLoad函数中增加对retrieveData的调用,代码如下所示:

    onLoad(options) {
        wx.getStorage({
            key: 'has_shown_splash',
            success: res => {
                this.retrieveData()
            },
            fail: err => {
                wx.redirectTo({
                    url: '/pages/douban/splash',
                })
            }
        })
    }

success是接口wx.getStorage异步调用成功后调用的函数。如果是首次进入小程序,没有找到缓存,则进入pages/douban/splash页面;反之,则调用自建的retrieveData函数,批量拉取豆瓣数据。

2.3.4 下载源码

在本节的学习过程中,如果遇到问题,可以通过如下方式来解决。

❑ 加入小程序微信群与作者及其他读者一同探讨。微信扫描前言中的二维码,关注“艺述思维”,发送“小程序”进群。

❑ 下载作者的源码,对照查找问题。在公众号中发送“豆豆电影2.3”获取下载地址。