本文配套视频地址:
v.qq.com/x/page/n055…
开始前请把
分支中的
- ch3-2
目录导入微信开发工具
- code/
文件,引入我们需要的外部资源
- index.js
- 'use strict';
- import util from '../../utils/index';
- import config from '../../utils/config';
- let app = getApp();
- let isDEV = config.isDev;
- // 后继的代码都会放在此对象中
- let handler = {
- }
- Page(handler)
我们首先挖出和渲染相关的数据,并添加在
对象的
- handler
字段中(Model 层)修改
- data
中的
- index.js
对象:
- handler
- // 此处省略部分代码
- let handler = {
- data: {
- page: 1, //当前加载第几页的数据
- days: 3,
- pageSize: 4,
- totalSize: 0,
- hasMore: true,// 用来判断下拉加载更多内容操作
- articleList: [], // 存放文章列表数据,与视图相关联
- defaultImg: config.defaultImg
- },
- }
注意: 后续添加的代码都是放在
对象中,它会传递到
- handler
函数中用来初始化页面组件
- Page
然后要做的就是获取列表的数据,初始化数据的工作我们一般放在生命周期的
里:
- onLoad()
- let handler = {
- onLoad(options) {
- this.requestArticle()
- },
- /*
- * 获取文章列表数据
- */
- requestArticle() {
- util.request({
- url: 'list',
- mock: true,
- data: {
- tag: '微信热门',
- start: this.data.page || 1,
- days: this.data.days || 3,
- pageSize: this.data.pageSize,
- langs: config.appLang || 'en'
- }
- }).then(res = >{
- console.log(res)
- });
- }
- }
修改
函数:
- requestArticle
- let handler = {
- // 此处省略部分代码
- requestArticle() {
- util.request({
- url: 'list',
- mock: true,
- data: {
- tag: '微信热门',
- start: this.data.page || 1,
- days: this.data.days || 3,
- pageSize: this.data.pageSize,
- langs: config.appLang || 'en'
- }
- }).then(res = >{
- // 数据正常返回
- if (res && res.status === 0 && res.data && res.data.length) {
- // 正常数据 do something
- console.log(res)
- }
- /*
- * 如果加载第一页就没有数据,说明数据存在异常情况
- * 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
- */
- else if (this.data.page === 1 && res.data && res.data.length === 0) {
- util.alert();
- this.setData({
- hasMore: false
- });
- }
- /*
- * 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
- */
- else if (this.data.page !== 1 && res.data && res.data.length === 0) {
- this.setData({
- hasMore: false
- });
- }
- /*
- * 返回异常错误
- * 展示后端返回的错误信息,并设置下拉加载功能不可用
- */
- else {
- util.alert('提示', res);
- this.setData({
- hasMore: false
- });
- return null;
- }
- })
- }
- }
上面我们把
重新包装成了
- wx.request
的形式,其实我们是请求的 mock 数据。但是接口请求到的数据绝大部分情况下都不会直接适用于
- Promise
展示,所以我们需要做一层数据转换,把接口数据转换成视图数据。
- UI
先看下后端返回的数据结构
我们需要做两件事情
数组,对返回的日期格式化,当天的显示
- data
,如果是今年的文章,显示月日格式
- 今天
;如果是往年的文章,显示标准的年月日格式
- 08-21
。
- 2015-06-12
数组,判断此篇文章的
- articles
是否已经在全局变量
- contentId
中,如果存在,说明已经访问过。
- visitedArticles
修改
,增加全局变量
- app.js
- visitedArticles
- globalData: {
- user: {
- name: '',
- avator: ''
- },
- visitedArticles: ''
- }
修改
中的
- index.js
函数:
- requestArticle
- let handler = {
- // 此处省略部分代码
- requestArticle() {
- // 注意:修改此处代码
- if (res && res.status === 0 && res.data && res.data.length) {
- let articleData = res.data;
- //格式化原始数据
- let formatData = this.formatArticleData(articleData);
- console.log(formatData)
- }
- }
- }
增加对列表数据格式化的代码:
- let handler = {
- // 此处省略部分代码
- /*
- * 格式化文章列表数据
- */
- formatArticleData(data) {
- let formatData = undefined;
- if (data && data.length) {
- formatData = data.map((group) = >{
- // 格式化日期
- group.formateDate = this.dateConvert(group.date);
- if (group && group.articles) {
- let formatArticleItems = group.articles.map((item) = >{
- // 判断是否已经访问过
- item.hasVisited = this.isVisited(item.contentId);
- return item;
- }) || [];
- group.articles = formatArticleItems;
- }
- return group
- })
- }
- return formatData;
- },
- /*
- * 将原始日期字符串格式化 '2017-06-12'
- * return '今日' / 08-21 / 2017-06-12
- */
- dateConvert(dateStr) {
- if (!dateStr) {
- return '';
- }
- let today = new Date(),
- todayYear = today.getFullYear(),
- todayMonth = ('0' + (today.getMonth() + 1)).slice( - 2),
- todayDay = ('0' + today.getDate()).slice( - 2);
- let convertStr = '';
- let originYear = +dateStr.slice(0, 4);
- let todayFormat = `$ {
- todayYear
- } - $ {
- todayMonth
- } - $ {
- todayDay
- }`;
- if (dateStr === todayFormat) {
- convertStr = '今日';
- } else if (originYear < todayYear) {
- let splitStr = dateStr.split('-');
- convertStr = `$ {
- splitStr[0]
- }年$ {
- splitStr[1]
- }月$ {
- splitStr[2]
- }日`;
- } else {
- convertStr = dateStr.slice(5).replace('-', '月') + '日'
- }
- return convertStr;
- },
- /*
- * 判断文章是否访问过
- * @param contentId
- */
- isVisited(contentId) {
- let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
- return visitedArticles.indexOf(`$ {
- contentId
- }`) > -1;
- },
- }
正常情况下,这个时候控制台打印出来的数据,是经过格式化的标准数据了,下一步,我们需要把它添加到
中的
- data
字段里面,这样视图才有了渲染的数据
- articleList
修改
,增加
- index.js
函数。由于每次请求的都是某一页的数据,所以在函数中,我们需要把每次请求过来的列表数据都
- renderArticle
(拼接)到
- concat
中:
- articleList
- let handler = {
- // 此处省略部分代码
- renderArticle(data) {
- if (data && data.length) {
- let newList = this.data.articleList.concat(data);
- this.setData({
- articleList: newList
- })
- }
- }
- }
在
函数中调用
- requestArticle
:
- renderArticle
- let handler = {
- // 此处省略部分代码
- requestArticle() {
- // 注意:修改此处代码
- if (res && res.status === 0 && res.data && res.data.length) {
- let articleData = res.data;
- //格式化原始数据
- let formatData = this.formatArticleData(articleData);
- this.renderArticle(formatData)
- }
- }
- }
最终的
文件就是这样的:
- index.js
- 'use strict';
- import util from '../../utils/index'import config from '../../utils/config'
- let app = getApp() let isDEV = config.isDev
- // 后继的代码都会放在此对象中
- let handler = {
- data: {
- page: 1,
- //当前的页数
- days: 3,
- pageSize: 4,
- totalSize: 0,
- hasMore: true,
- // 用来判断下拉加载更多内容操作
- articleList: [],
- // 存放文章列表数据
- defaultImg: config.defaultImg
- },
- onLoad(options) {
- this.requestArticle();
- },
- /*
- * 获取文章列表数据
- */
- requestArticle() {
- util.request({
- url: 'list',
- mock: true,
- data: {
- tag: '微信热门',
- start: this.data.page || 1,
- days: this.data.days || 3,
- pageSize: this.data.pageSize,
- langs: config.appLang || 'en'
- }
- }).then(res = >{
- // 数据正常返回
- if (res && res.status === 0 && res.data && res.data.length) {
- let articleData = res.data;
- //格式化原始数据
- let formatData = this.formatArticleData(articleData);
- this.renderArticle(formatData)
- }
- /*
- * 如果加载第一页就没有数据,说明数据存在异常情况
- * 处理方式:弹出异常提示信息(默认提示信息)并设置下拉加载功能不可用
- */
- else if (this.data.page === 1 && res.data && res.data.length === 0) {
- util.alert();
- this.setData({
- hasMore: false
- });
- }
- /*
- * 如果非第一页没有数据,那说明没有数据了,停用下拉加载功能即可
- */
- else if (this.data.page !== 1 && res.data && res.data.length === 0) {
- this.setData({
- hasMore: false
- });
- }
- /*
- * 返回异常错误
- * 展示后端返回的错误信息,并设置下拉加载功能不可用
- */
- else {
- util.alert('提示', res);
- this.setData({
- hasMore: false
- });
- return null;
- }
- })
- },
- /*
- * 格式化文章列表数据
- */
- formatArticleData(data) {
- let formatData = undefined;
- if (data && data.length) {
- formatData = data.map((group) = >{
- // 格式化日期
- group.formateDate = this.dateConvert(group.date);
- if (group && group.articles) {
- let formatArticleItems = group.articles.map((item) = >{
- // 判断是否已经访问过
- item.hasVisited = this.isVisited(item.contentId);
- return item;
- }) || [];
- group.articles = formatArticleItems;
- }
- return group
- })
- }
- return formatData;
- },
- /*
- * 将原始日期字符串格式化 '2017-06-12'
- * return '今日' / 08-21 / 2017-06-12
- */
- dateConvert(dateStr) {
- if (!dateStr) {
- return '';
- }
- let today = new Date(),
- todayYear = today.getFullYear(),
- todayMonth = ('0' + (today.getMonth() + 1)).slice( - 2),
- todayDay = ('0' + today.getDate()).slice( - 2);
- let convertStr = '';
- let originYear = +dateStr.slice(0, 4);
- let todayFormat = `$ {
- todayYear
- } - $ {
- todayMonth
- } - $ {
- todayDay
- }`;
- if (dateStr === todayFormat) {
- convertStr = '今日';
- } else if (originYear < todayYear) {
- let splitStr = dateStr.split('-');
- convertStr = `$ {
- splitStr[0]
- }年$ {
- splitStr[1]
- }月$ {
- splitStr[2]
- }日`;
- } else {
- convertStr = dateStr.slice(5).replace('-', '月') + '日'
- }
- return convertStr;
- },
- /*
- * 判断文章是否访问过
- * @param contentId
- */
- isVisited(contentId) {
- let visitedArticles = app.globalData && app.globalData.visitedArticles || '';
- return visitedArticles.indexOf(`$ {
- contentId
- }`) > -1;
- },
- renderArticle(data) {
- if (data && data.length) {
- let newList = this.data.articleList.concat(data);
- this.setData({
- articleList: newList
- })
- }
- }
- }
- Page(handler)
下一篇中,我们将会把数据与视图层结合在一起,动态的展示视图层
iKcamp官网:www.ikcamp.com
访问官网更快阅读全部免费分享课程:《iKcamp出品|全网最新|微信小程序|基于最新版1.0开发者工具之初中级培训教程分享》。
包含:文章、视频、源代码
iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。
报名地址:www.huodongxing.com/event/54099…
与
小程序总榜排名第四、教育类排名第一的研发团队,面对面沟通交流。
- “天天练口语”
来源: https://juejin.im/post/59f0095b6fb9a0450d1048f4