原生框架开发入门(三) —— 博客首页文章列表实现(下)
在上一篇教程中,我们通过测试数据渲染了小程序首页的文章列表,这一篇教程我们将通过访问后端 API 接口来获取文章数据,以便实现首页文章渲染、刷新和翻页操作。
提供后端 API 接口
定义路由
首先,我们需要在博客项目 blog57
的 routes/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 接口获取文章数据渲染的首页了:
需要注意的是,后端接口域名需要在小程序开发配置那里提前配置好,否则不能访问后端 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)
})
重新编译小程序后,一直上拉,最后会提示没有更多文章:
onPullDownRefresh
此外,你还可以通过编写 onPullDownRefresh
函数来处理下拉刷新事件,也比较简单,参考官方文档及上述上拉触底处理函数示例代码实现即可。
分享小程序
最后,我们通过编写页面事件处理函数 onShareAppMessage
实现小程序分享功能:
onShareAppMessage() {
return {
title: 'Laravel学院',
path: '/pages/index'
}
},
基本的分享功能非常简单,我们只需要返回小程序页面标题和对应的路径信息即可,这样我们点击小程序首页右上角的「...」即可看到转发按钮了:
点击「转发」按钮,就可以将小程序首页分享给其他人了:
好了,有关小程序版博客应用首页我们就讲到这里,下篇教程我们将通过原生框架实现小程序版博客详情页。
6 Comments
您好! 这个接口https://blog.laravelacademy.org/api/v1/articles?page=1 好像挂掉了!能不能麻烦修复一下呢?
服务器过期了 没续费。。。 我近期恢复下
刷新要调用一下重新加载吧?
Cannot read property 'concat' of undefined;at api request success callback function TypeError: Cannot read property 'concat' of undefined这个concat函数怎么回事,还是返回的数据格式不对呢
crsf 怎么解决?
大佬,http://blog57.test/api/v1/articles 接口似乎又挂了...