微信小程序开发入门教程(五):原生框架开发入门 —— 博客首页文章列表实现(下)

上一篇教程中,我们通过测试数据渲染了小程序首页的文章列表,这一篇教程我们将通过访问后端 API 接口来获取文章数据,以便实现首页文章渲染、刷新和翻页操作。

提供后端 API 接口

定义路由

首先,我们需要在博客项目 blog57routes/api.php 中定义一个 API 路由:

Route::middleware('throttle:60,1')->prefix('v1')->group(function() {
    Route::get('/articles', 'API\PostController@index');
});

我们给这个 API 接口加上 v1 前缀,并且应用了频率限制中间件(1分钟限制访问60次),然后通过 /api/v1/articles 获取首页文章列表,翻页和刷新都是这一个路由实现。

编写控制器方法

接下来,我们需要创建一个新的控制器 API/PostController

php artisan make:controller API/PostController

在新创建的控制器中新增一个 index 方法:

public function index(Request $request)
{
    // 每页显示5条记录
    $posts = Post::orderBy('published_at', 'desc')->simplePaginate(5);
    $items = [];
    foreach ($posts->items() as $post) {
        $item['id'] = $post->id;
        $item['title'] = $post->title;
        $item['summary'] = $post->subtitle;
        $item['thumb'] = url(config('blog.uploads.webpath') . '/' . $post->page_image);
        $item['posted_at'] = $post->published_at;
        $item['views'] = mt_rand(1, 10000); // 暂时没有实现文章浏览数逻辑,返回随机数
        $items[] = $item;
    }
    $data = [
        'message' => 'success',
        'articles' => $items
    ];
    return response()->json($data);
}

我们通过 Laravel 框架内置的分页器进行分页,每页显示 5 条记录,页码由底层通过请求参数中的 page 值进行判定。然后我们重新组装文章数据并返回。

测试 API 接口访问

这样,我们就可以通过 http://blog57.test/api/v1/articles 访问博客文章列表了:

你还可以通过传递页码 http://blog57.test/api/v1/articles?page=2 访问分页数据。

测试完成后将修改代码提交、上线,以便在线上可以通过小程序配置的域名 blog.laravelacademy.org 访问。

在小程序首页通过 API 获取文章数据

正如开篇所说,在上篇教程中学院君是通过填充测试数据渲染文章列表的,现在,我们将其修改为通过后台 API 获取文章数据。

回到微信小程序项目,打开 pages/index/index.js 文件,删除测试文章数据:

data: {
    articles: [],
    isLoadingMore: false,
    currentPage: 1,
    info: ''
},

然后我们在 Page 对象中新增一个 loadArticles 方法用于从后端 API 接口获取文章数据并设置到 data 中的 articles 属性上:

loadArticles: function () {
    var that = this
    wx.request({
      url: `https://blog.laravelacademy.org/api/v1/articles?page=${that.data.currentPage}`,
      success: (res) => {
        if (res.data.message === 'success') {
          that.setData({
            articles: res.data.articles
          })
        } else {
          that.setData({
            info: '加载文章列表失败,请重试'
          })
        }
        wx.hideLoading()
      }
    })
}

这里我们通过 wx.request 发起异步请求,从博客后端 API 接口获取文章列表,如果获取成功,则通过返回文章数据设置 articles 属性,否则通过 info 属性提示用户加载失败。setData 函数用于将数据从逻辑层异步发送到视图层,同时同步改变对应的 this.data 的值(更多细节请查看小程序文档)。

接下来,我们要在 onLoad 里调用这个方法,以便页面加载完成后就能看到文章列表数据:

onLoad: function () {
    wx.showLoading({
      title: '文章加载中...'
    })
    this.loadArticles()
},

onLoad 是小程序的生命周期函数,会在页面加载的时候触发,更多小程序生命周期函数可以在小程序官方文档查看。

这样,重新编译后,就可以在微信开发者工具左侧预览界面看到通过 API 接口获取文章数据渲染的首页了:

-w341

需要注意的是,后端接口域名需要在小程序开发配置那里提前配置好,否则不能访问后端 API,会报错:

通过监听上拉触底事件进行翻页

从后端 API 获取文章数据渲染首页列表后,并不意味着首页就一成不变了,为了提升用户体验,我们还可以监听页面事件,并编写对应的页面事件处理函数。这里我们将通过编写上拉触底事件处理函数实现翻页功能。

onReachBottom

上拉触底对应的页面事件函数是 onReachBottom,在该函数中我们实现翻页功能如下:

onReachBottom: function() {
    this.data.currentPage++
    if (this.data.isLoadingMore && this.data.currentPage > 20) { 
      // 最多只能加载20页
      this.data.isLoadingMore = false
      this.data.info = '没有更多文章了'
      return
    }
    this.data.isLoadingMore = true
    this.loadArticles()
},

每次触底后我们将 currentPage 值加 1,如果 isLoadingMore 值为 false,或者 currentPage 值超过 20,则提示没有更多文章,否则继续通过 loadArticles 加载更多文章,此时,loadArticles 函数也要做调整:

loadArticles: function () {
    var that = this
    wx.request({
      url: `https://blog.laravelacademy.org/api/v1/articles?page=${that.data.currentPage}`,
      success: (res) => {
        if (res.data.message === 'success') {
          if (res.data.articles.length == 0) {
            that.setData({
              isLoadingMore: false,
              info: '没有更多文章了'
            });
          }
          that.setData({
            articles: that.data.articles.concat(res.data.articles)
          })
        } else {
          that.setData({
            info: '加载文章列表失败,请重试'
          })
        }
        wx.hideLoading()
      }
    })
}

这里新增的逻辑是当分页获取结果为空时,意味着没有更多文章了,需要对用户进行提示,并且不能再继续翻页了,此外,我们还将分页获取的文章数据和当前页的文章数据合并后显示,否则按之前的逻辑只能显示某个分页的数据:

that.setData({
    articles: that.data.articles.concat(res.data.articles)
})

重新编译小程序后,一直上拉,最后会提示没有更多文章:

-w344

onPullDownRefresh

此外,你还可以通过编写 onPullDownRefresh 函数来处理下拉刷新事件,也比较简单,参考官方文档及上述上拉触底处理函数示例代码实现即可。

分享小程序

最后,我们通过编写页面事件处理函数 onShareAppMessage 实现小程序分享功能:

onShareAppMessage() {
    return {
      title: 'Laravel学院',
      path: '/pages/index'
    }
},

基本的分享功能非常简单,我们只需要返回小程序页面标题和对应的路径信息即可,这样我们点击小程序首页右上角的「...」即可看到转发按钮了:

-w332

点击「转发」按钮,就可以将小程序首页分享给其他人了:

-w325

好了,有关小程序版博客应用首页我们就讲到这里,下篇教程我们将通过原生框架实现小程序版博客详情页。

学院君 has written 1199 articles

Laravel学院院长,终身学习者

积分:157992 等级:P12 职业:手艺人 城市:杭州

4 条回复

  1. 塔夫 塔夫 says:

    Cannot read property 'concat' of undefined;at api request success callback function TypeError: Cannot read property 'concat' of undefined这个concat函数怎么回事,还是返回的数据格式不对呢

  2. yycu yycu says:

    您好! 这个接口https://blog.laravelacademy.org/api/v1/articles?page=1 好像挂掉了!能不能麻烦修复一下呢?

登录后才能进行评论,立即登录?