[转]灯灯小程序开发手记:仿今日头条(上)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转]灯灯小程序开发手记:仿今日头条(上)相关的知识,希望对你有一定的参考价值。
本文转自:http://www.jianshu.com/p/a1e0b8abb12d
写在前面
新的一年,祝大家新年快乐!当然对于程序员来说,新的一年,也要有新的改变。因此灯灯决定凑热闹编写微信小程序啦! 上一篇文章《记一次小程序开发过程》中,灯灯大致写了下自己第一次开发小程序的感受和流程。这一次灯灯会详细记录下自己制作一个小程序的思路、遇到的问题、涉及到的代码等和大家分享。 视频教程地址:http://study.163.com/course/introduction.htm?courseId=1003606050
要做个什么
首先我们要确定做一个什么小程序,我决定先做一个很常规的新闻App练练手,样式就模仿头条啦! 开发分为两次进行,第一次完成新闻列表、内容阅读这两个常规功能,不涉及用户交互。第二次完善功能,加上评论、收藏等互动功能。 本文就和大家一起来制作第一个无用户系统版本。 应用构架非常简单,就是2个页面:新闻列表、新闻详情。
当然样式不一定要做那么复杂先,比如我们就统一1幅封面预览图,暂时不做3幅图的item。
动手开发
首先是首页,即新闻列表
布局上,顶部一个悬浮固定的分类条,用横向的scroll-view即可实现。下面是列表,循环渲染每个item即可。
分类布局代码如下:
<scroll-view class="segments" scroll-x="true">
<view wx:for="{{sections}}" class="section {{item.active ? ‘active‘ : ‘‘}}" data-sid="{{item.section_id}}" bindtap="onSectionClicked">
<text>{{item.name}}</text>
</view>
</scroll-view>
分类样式代码如下:
.segments{
width:100%;
height:35px;
background: #f6f6f6;
white-space: nowrap;
font-size:15px;
position: fixed;
top: 0;
z-index:1;
}
.section{
width:20%;
height:100%;
text-align: center;
color:#000;
display: inline-block;
line-height: 35px;
}
.section.active{
color:#d43d3d;
}
注意这边有个active类,就是当前选中的分类,我把字体颜色设为了红色,当然你也可以加个横线。
文章列表布局如下:
<!--文章列表-->
<view class="articles">
<view wx:for="{{articles}}" class="article" data-aid="{{item.article_id}}" bindtap="onArticleClicked">
<view class="left">
<view class="title">
{{item.title}}
</view>
<view class="subTitle">
<!--这边可以加副标题-->
</view>
<view class="date">
<text>{{item.date}}</text>
</view>
<view class="cnt">
<text>阅读:{{item.read_cnt}}</text>
</view>
</view>
<view class="right">
<image src="{{item.cover1}}"/>
</view>
<view style="clear:both"></view>
</view>
</view>
Js逻辑代码如下:
var app = getApp()
var sectionData = null
var currentSectionIndex = 0
Page({
data: {},
onLoad: function () {
var that = this
//获取分类信息
wx.request({
url : ‘http://你的服务器/news/section‘,
data : {},
success : function(res){
sectionData = res.data.sections;
sectionData[0][‘active‘] = true //默认选中第一个分类
that.loadArticles(sectionData[0][‘section_id‘])
that.setData({
sections : sectionData
});
}
})
},
onSectionClicked: function(e){
var sid = e.currentTarget.dataset.sid;
//刷新选中状态
for(var i in sectionData){
if(sectionData[i][‘section_id‘] == sid){
sectionData[i][‘active‘] = true
currentSectionIndex = i
}
else
sectionData[i][‘active‘] = false
}
this.setData({
sections : sectionData
});
//加载文章
if(sectionData[i][‘articles‘]){
this.setData({
articles : sectionData[i][‘articles‘]
});
}else{
this.loadArticles(sid)
}
},
loadArticles: function(section_id){
var that = this
//获取文章列表
wx.request({
url : ‘http://你的服务器/news/article‘,
method: ‘POST‘,
data : {
section_id:section_id,
start_id:0,
limit:10
},
header: {
‘Content-Type‘: ‘application/x-www-form-urlencoded‘
},
success : function(res){
var articleData = res.data.articles;
sectionData[currentSectionIndex][‘articles‘] = articleData
that.setData({
articles : articleData
});
}
})
},
onArticleClicked: function(e){
var aid = e.currentTarget.dataset.aid
wx.navigateTo({
url: ‘/pages/detail/detail?article_id=‘+aid
})
}
})
解释一下,就是从服务器获取分类信息,然后根据分类的section_id再去获取分类下的文章列表,这边照理说是要实现下拉刷新和无限加载的,第一版暂时不做,所以参数里面start_id和limit我写死了。 这边我为了防止重复请求服务器,把每次分类请求完的数据都记录下来了,详情见onSectionClicked事件的处理。
注意:POST请求时,header参数要写成‘Content-Type‘: ‘application/x-www-form-urlencoded‘,不然服务器得不到post参数,很奇怪
这边有个问题是横向的scroll-view不能隐藏滚动条,非常难看,我没有查到解决办法,希望知道的朋友留言说下。
最终效果图(数据是我以前做的一个藏文化App的数据,不要见怪哈哈):
然后是文章详情
这边我本来要放弃去做了,因为当时做后台接口的时候文章content是以html代码形式记录的,然后客户端直接webview去解析。但是现在微信小程序并不支持富文本、也不支持iframe、也不支持外链视频。但是偶然间我看见了一个神器: wxParse微信小程序富文本解析 Github 正好实现了我需要的富文本解析功能,而且图片还自带懒加载、自带全屏浏览功能,感谢作者。
所以详情页的JS代码非常简单:
var WxParse = require(‘../../wxParse/wxParse.js‘);//引入解析库
var article_id = ‘‘
Page({
data:{},
onLoad:function(options){
var that = this
article_id = options.article_id // 获取文章id
wx.request({
url : ‘http://你的服务器/news/detail‘,
method: ‘POST‘,
data : {
article_id: article_id
},
header: {
‘Content-Type‘: ‘application/x-www-form-urlencoded‘
},
success : function(res){
var _content = res.data.article[‘content‘]
that.setData({
article: res.data.article
});
WxParse.wxParse(‘content‘, ‘html‘, _content, that,0);//富文本解析
}
})
}
})
布局代码中:
<!--引入库-->
<import src="../../wxParse/wxParse.wxml"/>
<!--...其他布局省略-->
<!--解析生成-->
<template is="wxParse" data="{{wxParseData:content.nodes}}"/>
当然别忘了在样式代码里也引入:
@import "/wxParse/wxParse.wxss";
最终效果图,点击图片还支持全屏浏览,非常人性化:
总结
至此,一个简单的头条的就开发完了。看起来很容易但实际做的时候会遇到很多莫名的bug,主要原因还是微信提供的那一套东西问题太多了。例如:不支持富文本、不支持外链、滚动条不能隐藏、百分比布局有时候有问题...... 当然我相信之后微信也会一次次迭代一次次修复加强的,所以也不用太担心,毕竟微信小程序的理念就是简单,设计得太复杂就没有意义了。
Todo
- 增加3幅图片的item样式
- 增加下拉刷新、无限加载
- 增加用户登陆
- 增加收藏功能
- 增加评论功能
这些功能灯灯会在开发完成后继续和大家分享,目前源码由于功能不完整暂时没有在Github上开源,等做完后我再一起开源。对了,整个后台系统是用Thinkphp做的,其实并不难,有兴趣的同学可以自己学学。 Github开源地址:https://github.com/winterfeel/Wxapp_Toutiao 视频教程地址:http://study.163.com/course/introduction.htm?courseId=1003606050
灯灯小程序开发手记:仿今日头条(下)
http://www.jianshu.com/p/b17933c238d7
接着上一篇
上一篇文章中,我们已经完成了头条的新闻列表、新闻详情功能了,但是还存在一些值得优化的地方,以及评论功能没有加上。 欢迎Star Github开源地址:https://github.com/winterfeel/Wxapp_Toutiao 视频教程地址:http://study.163.com/course/introduction.htm?courseId=1003606050 所以在这一篇中我们进行以下优化:
- 下拉刷新、无限加载
- 评论显示
收藏功能
说明下为什么不做收藏功能,其实是设计到用户登陆功能暂时都不做了,包括发表评论。原因:
微信小程序登陆需要有appid,appid需要公司资质去申请,每个公司申请的数量有限制(好像是30个),每个身份证也只能最多绑定5个。 虽然网上流传着个人即使申请失败也可以获得appid,但是就此失去了一次绑定机会,个人建议还是不要浪费。所以小程序中的登陆、评论、收藏功能此处暂时不做。
刷新优化
微信小程序原生提供了下拉刷新和加载更多事件,这一点还是比较人性化的。 首先需要在配置文件,即页面.json,如index.json添加允许下拉刷新:
{
"enablePullDownRefresh":true
}
然后在js代码中添加响应事件:
//下拉刷新
onPullDownRefresh: function(){
this.loadArticles(sectionData[currentSectionIndex][‘section_id‘],false)
},
//加载更多
onReachBottom: function () {
this.loadArticles(sectionData[currentSectionIndex][‘section_id‘],true)
}
注意我把加载更多和下拉刷新所用的请求方法写成了一个函数:
loadArticles: function(section_id,ifLoadMore) //分类id、是否是加载更多
这个ifLoadMore起区分的作用,如果是false,则将获得的数据直接替换;如果是true,则将获得的数据追加在原有的数据后面。
if(ifLoadMore){
//加载更多
if(articleData){
sectionData[currentSectionIndex][‘articles‘] = sectionData[currentSectionIndex][‘articles‘].concat(articleData)//追加
}else{
wx.showToast({
title: ‘暂无更多内容‘,
icon: ‘loading‘,
duration: 2000
})
}
}else{
sectionData[currentSectionIndex][‘articles‘] = articleData//刷新
}
这样就不需要分开写2种请求代码了。当然我们需要添加一个loading动画,有一点我不明白的是微信把loading动画当初了组件...只能强行用一个hidden参数来改变它的隐藏和展示状态,太坑了。 有同学说不是有showToast吗?是的,showToast最多可以显示10秒,虽然理论上是够了,但是这样总是很蛋疼,并不能真实地去控制显示因此。
评论功能
虽然不打算做发表评论功能了,但是布局我还是加了上去,效果如图:
评论列表还是用for循环渲染每个item即可,当然这边我添加了一个小细节,当没有评论的时候会显示一个空提示:
只需要一个简单的if判断就可以啦:
<view wx:if="{{commentList}}">
<view class="comment" wx:for="{{commentList}}">
<view class="avatar">
<image src="{{item.avatar}}" mode="scaleToFill"></image>
</view>
<view class="commentInfo">
<view class="userName">{{item.username}}<view class="time">{{item.time}}</view></view>
<view class="commentContent"><text class="reply" wx:if="{{item.parent_username}}">回复@{{item.parent_username}}:</text>{{item.content}}</view>
</view>
</view>
</view>
<view class="noComment" wx:else>
<text>暂无评论,赶快抢沙发吧!</text>
</view>
</view>
这边还有一个细节是,可以显示回复XX。当时在设计后台的时候允许回复他人,即评论可以有一个parent_userid字段,代表你所回复的这个用户的id,当然最后服务器返回的时候会返回用户名。 所以判断下wx:if="{{item.parent_username}}" 即可得出该评论是直接评论还是回复他人的评论。 其实发表评论的代码我也写了,很简单就是一个post请求,但是由于无法登陆,并没有真正去调用。
由于微信没有提供元素获取功能,所以想要获取评论框里的内容不好直接get,只能给输入框绑定change事件,然后在事件里把内容复制给一个变量才行。如果有其他方法,欢迎留言指点。
总结开源
至此,一个小头条就完成了,当然由于缺失了用户系统,功能肯定是不完善的,理论上也是毫无用处的。所以真正的小程序产品肯定不应该是纯粹的内容展示,交互一定是个很重要的环节。 我的代码可能在很多地方都不够严谨、不够细致,大家如果需要参考欢迎访问Github给个star。 Github开源地址:https://github.com/winterfeel/Wxapp_Toutiao 我更享受的是产品的设计过程,所以小程序一定会带给我很多乐趣。后续我会继续制作更多小程序,并且发布一些教程,喜欢的朋友可以继续关注! 注:此文为灯灯原创,可转载,注明出处即可。 灯灯微信,添加请注明理由。小程序商城解决方案,最低1000元起即可拥有,欢迎联系!
视频教程地址:http://study.163.com/course/introduction.htm?courseId=1003606050
以上是关于[转]灯灯小程序开发手记:仿今日头条(上)的主要内容,如果未能解决你的问题,请参考以下文章