您的位置:首页 > 移动开发 > 微信开发

微信小程序开发入门第七章:收藏、评论、点赞及计数功能

2018-03-25 18:54 645 查看
    本章内容有一定的难度,但其中的技巧和知识还是很丰富的。本章通过编写几乎所有内容型应用都会附带的“评论”“点赞”“阅读计数”“收藏”等功能,来学习使用小程序的交互反馈组件、缓存的应用、图片选择和预览、屏蔽关键字、录音、拍照以及播放录音等功能

7.1 收藏、评论、点赞、计数功能准备工作

7.1 收藏、评论、点赞、计数功能准备工作接下来我们将要连续实现4个非常有意思的功能,这些功能在内容型应用中是非常常见的,分别是收藏、点赞、评论和计数。我们先来编写收藏、评论和点赞的功能按钮。阅读计数是一项被动功能,无须用户有意识地主动触发。在post-detail.wxml中新增一段工具栏代码。代码清单  7-1      编写3个功能的功能按钮                                post-detail.wxml<!--pages/post/post-detail/post-detail.wxml-->
<view class="container">
<image class="head-image" src="{{post.postImg}}"></image>
<text class="title">{{post.title}}</text>
<view class="author-date">
<view class="author-box">
<image class="avatar" src="{{post.avatar}}"></image>
<text class="author">{{post.author}}</text>
</view>
<text class="date">{{post.dataTime}}</text>
</view>
<text class="detail">{{post.detail}}</text>
</view>

<view class="tool">
<view class="tool-item" catchtap='onUpTop' data-post-id="{{post.postId}}">
<image src="/images/icon/wx_app_like.png"></image>
<text>{{post.upNum}}</text>
</view>
<view class="tool-item comment" catchtap='onCommentTap' data-post-id="{{post.postId}}">
<image src="/images/icon/wx_app_message.png"></image>
<text>{{post.commentNum}}</text>
</view>
<view class="tool-item" catchtap='onCollectionTap' data-post-id="{{post.postId}}">
<image src="/images/icon/wx_app_collected.png"></image>
<text>{{post.upNum}}</text>
</view>
</view>在post-detail.wxml页面的container中添加了一段<view class="tool">的相关代码。该代码实现了收藏、评论和点赞3个功能按钮。每个功能按钮都绑定了对应的点击事件,注意view组件上的catchtap属性。除此之外,我们还在每个功能按钮上使用data-post-id绑定了当前文章的id号。upNum、commentNum和collectionNum等数据已经在5.13小节中全部添加到了data.js文件中。接着编写3个功能按钮的样式代码清单 7-2      编写3个功能按钮的样式                                    post-detail.wxss
.tool{
height: 64rpx;
text-align: center;
line-height: 64rpx;
margin: 20rpx 28rpx 20rpx 0;
}
.tool-item{
display: inline-block;
vertical-align: top;
margin-right: 30rpx;
}
.tool-item image{
height: 30rpx;
width: 30rpx;
vertical-align: -3px;
margin-right: 10rpx;
}
.comment image{
transform: scale(.85);
}保存刷新后,3个功能按钮将出现在post-detail页面的正下方,如图7-1所示。



图7-1 3个功能按钮的样式和位置

7.2 文章收藏功能

7.2 文章收藏功能我们首先来实现文章收藏功能。文章收藏功能需要记录两个变量值:
自己是否收藏了文章。如果自己收藏了,那么需要将收藏的图片更换为已收藏。

所有用户收藏文章的总数量。需要注意的是,由于我们的数据库只在本地,无法多次收藏同一篇文章,所以收藏数量永远只能在初始数量的基础上+1或者-1,分别对应取消收藏和点击收藏两种状态。但在真实的项目中,这个收藏数量却是要受到所有用户取消、收藏文章动作影响的。同样的情况也会出现在“文章点赞”这个功能里。

当页面从post跳转到post-detail时,我们就需要知道该文章是否已被用户收藏。在data.js中,我们使用collectionStatus这个属性表示文章是否已被收藏,这个变量的类型是Boolean。那么如何根据collectionStatus这个变量的取值来动态切换收藏图标呢?熟悉传统Web开发的读者很容易想到用jQuery获取image标签,再动态地设置image的src属性。再次强调,小程序没有dom,一切都是数据绑定,请抛弃dom的思维方式。7.2.1 条件渲染:wx:if与wx:elsecollectionStatus只有两种取值:true或者false。我们需要做的是,当collectionStatus为false时,显示图7-2未收藏状态的图标,而当collectionStatus为true时,显示图7-3收藏状态的图标。


以上需求是不是就是编程中非常经典的if else?如果wxml组件也像js代码一样有if else就可以解决动态显示收藏图片的问题。下面来看看如何实现这个功能。小程序提供了wx:if与wx:else来实现条件渲染。当变量为true时,执行wx:if,否则将执行wx:else。修改收藏按钮的wxml代码如下:代码清单  7-3  条件渲染                                               post-detail.wxml
<view class="tool-item" catchtap='onCollectionTap' data-post-id="{{post.postId}}">
<image wx:if="{{post.collectionStatus}}" src="/images/icon/wx_app_collected.png"></image>
<image wx:else src="/images/icon/wx_app_collect.png"></image>
<text>{{post.collectionNum}}</text>
</view>上述代码中我们添加了两个image组件,分别是收藏和未收藏图片。这两个image组件各有一个wx:if和wx:else属性。当post.collectionStatus为true时将显示wx_app_collected.png图片,而当post.collectionStatus为false时将显示wx_app_collect.png图片。由于我们已经在data.js文件中将部分文章的收藏状态设置为true,因此保存并运行项目,发现所有collectionStatus为true的文章,其收藏图片都将显示wx_app_collected.png,如图7-4所示。

图7-4 显示wx_app_collected.pngwx:if与wx:else的条件渲染在小程序中被大量使用,不仅仅被用来做图片的更换,还可以用来控制元素的显示和隐藏。wx:if可以被单独使用,并不一定要同wx:else一起使用。除此之外,条件渲染还可以做多级别的if else,如代码清单7-4的示例代码所示。


如果变量length的取值大于5,那么将显示数字1。如果变量length的取值大于2且小于等于5,那么将显示数字2。以上条件都不满足,就显示数字3。你还可以添加更多的elif分支,以实现更多级别的条件判断。7.2.2 实现收藏点击功能在7.2.1小节中,我们仅仅是在post-detail页面加载时读取了该文章对于当前用户是否为收藏状态,并正确地设置和显示了这个状态。在这个小节中,我们将实现用户点击图片进行文章的收藏和取消收藏功能。首先我们继续完善DBPost这个数据库操作类。在DBPost类中添加一个方法,用以处理文章的收藏操作。代码清单 7-5  添加处理文章收藏的方法                                   DBPost.js
//收藏文章
collect()
{
return this.updatePostData('collect');
}该方法中调用了DBPost类的updatePostData方法,这个方法我们还没有编写。在DBPost类中添加updatePostData方法。该方法是处理点赞、评论、收藏、阅读的核心方法。
代码清单  7-6  添加updatePostData方法                                DBPost.js

//更新本地的点赞、评论信息、收藏、阅读量
updatePostData(category){
var itemData = this.getPostItemById(),
postData = itemData.data,
allPostData = this.getAllPostData();
switch(category){
case 'collect':
//处理收藏
if(!postData.collectionStatus){
//如果当前状态是未收藏
postData.collectionNum++;
postData.collectionStatus = true;

c249
}else{
//如果当前状态是已收藏
postData.collectionNum--;
postData.collectionStatus = false;
}
break;
default:break;
}
//更新缓存数据库
allPostData[itemData.index] = postData;
this.execSetStorageSync(allPostData);
return postData;
}
我们目前仅处理collect这一种操作,后续我们将继续在代码清单7-6的switch case中添加评论、阅读数、点赞等处理分支。这样,DBPost就具备了处理文章收藏的能力。当用户点击收藏按钮后,在点击事件函数中调用DBPost的collect方法即可。处理文章收藏动作的事件函数是onCollectionTap,这个事件函数已在代码清单7-1中被注册在了收藏功能按钮上。我们只需要在post-detail.js中编写这个方法即可代码清单   7-7编写onCollectionTap方法                                            post-detail.jsnCollectionTap:function(event){
//dbpost对象已在onLoad函数中被保存到了this变量中,无需再次实例化
var newData = this.dbPost.collect();
//从新绑定数据,注意,不要将整个newData全部作为setData的参数,应当有选择的更新部分数据
this.setData(
{
'post.collectionSataus':newData.collectionStatus,
'post.collectionNum':newData.collectionNum
}
)
}7.2.3 交互反馈wx:showToast现在,我们已经实现了文章的收藏与取消收藏功能,但收藏功能的体验并不好,用户在收藏和取消收藏后没有任何交互反馈提示。小程序提供了一些交互反馈API来帮助开发者处理交互相关的问题。目前,小程序提供了以下4个交互反馈API:wx.showToast

wx.hideToast

wx.showModal

wx.showActionSheet

我们选用wx.showToast(object)来制作文章收藏功能的交互反馈。代码清单 7-8  文章收藏功能的交互反馈                              post-detail.js
//交互反馈
wx.showToast({
title:newData.collectionStatus?"收藏成功":"收藏取消",
duration:1000,
icon:"sucess",
make:true
})
其中,object参数的title属性用于设置提醒消息的内容;duration设置提醒的自动消失时间,最长10000毫秒,默认值为1500毫秒;icon可以设置一个小图标,其取值只能是success和loading;mask指定是否显示透明的蒙层,以防止触摸穿透,默认值为false。mask主要用来防止用户连续点击收藏按钮。开发者可执行尝试将mask设置为true和false时的不同效果:当mask为true时连续点击收藏图标,图标不会连续做出收藏/取消收藏的响应;当mask为false时,就会不停地响应用户的点击操作。wx.showToast的效果如图7-5所示。


图7-5 wx.showToast效果

7.3 文章点赞功能

7.3 文章点赞功能文章点赞功能的实现思路同收藏几乎是一样的。首先在DBPost.js中增加点赞的方法。代码清单7-9   添加处理点赞操作的方法                           DBPost.js
//点赞或取消点赞
up(){
return this.updatePostData('up');

}接着在DBPost的updatePostData方法中处理当case为up时的情况。下面给出updatePostData的全部代码。
代码清单  7-10  增加case为up时的处理方法                                                DBPost.js
//更新本地的点赞、评论信息、收藏、阅读量
updatePostData(category){
var itemData = this.getPostItemById(),
postData = itemData.data,
allPostData = this.getAllPostData();
switch(category){
case 'collect':
//处理收藏
if(!postData.collectionStatus){
//如果当前状态是未收藏
postData.collectionNum++;
postData.collectionStatus = true;
}else{
//如果当前状态是已收藏
postData.collectionNum--;
postData.collectionStatus = false;
}
break;
case 'up':
if(!postData.upStatus){
postData.upNum++;
postData.upStatus = true;
}else{
postData.upNum--;
postData.upStatus = false;
}
break;

default:break;
}
//更新缓存数据库
allPostData[itemData.index] = postData;
this.execSetStorageSync(allPostData);
return postData;
}代码清单7-10同代码清单7-6相比,仅仅增加了case为'up'时的这段代码。很明显,我们可以看到处理点赞的逻辑同处理收藏时的逻辑几乎一样:改变upStatus的状态,并对upNum这个计数变量做相应的增减操作。我们编写完DBPost中关于点赞的接口后,接着编写post-detail.js和post-detail.wxml中关于点赞的相关代码。
代码清单 7-11      编写onUpTap方法                                       post-detail.js
onUpTap:function(event){
var newData = this.dbPost.up();
this.setData({
'post.upStatus':newData.upStatus,
'post.upNum':newData.upNum,
})
wx.showToast({
title: newData.upStatus ? "点赞成功" : "点赞取消",
duration: 1000,
icon: "sucess",
make: true
})
onUpTap方法响应用户点赞的动作。当用户点击点赞按钮后,onUpTap方法将调用DBPost的up方法并将返回的最新数据使用this.setData更新。类似于收藏功能,我们还需要使用条件渲染wx:if改写wxml中的点赞按钮。代码清单  7-12     点赞功能的条件渲染                             post-detail.wxml
<view class="tool-item" catchtap='onUpTap' data-post-id="{{post.postId}}">
<image wx:if="{{post.upStatus}}" src="/images/icon/wx_app_liked.png"></image>
<image wx:else  src='/images/icon/wx_app_like.png'></image>
<text>{{post.upNum}}</text>
</view>
以上代码将在post.upStatus为true时显示wx_app_liked.png,当post.upStatus为false时显示wx_app_like.png。在编写完以上代码后,保存运行项目,点击点赞按钮,图片会不断切换,点赞数也将相应地+1或者-1。很多开发者可能还不太习惯使用数据绑定的方式来做样式、状态的切换,但数据绑定的写法确实非常简化、方便。我们只需要在js中改变各类变量的状态和值,前端组件就会响应我们的操作,动态地做出变化。

7.4 本地缓存的重要性及应用举例

提供本地的key&value缓存机制是小程序的一大特点,善用本地缓存将可以极大地改善客户端的体验与服务器的性能。前几个小节中,我们大量地使用了本地缓存来模拟服务器的数据库。这样做一方面是因为我们并没有真实的服务器,必须依靠客户端的缓存能力来记录数据;另一方面是因为即使在真实的项目中我们拥有自己的远程服务器,也依然需要在客户端管理本地缓存。举个例子,如果我们要实现一个城市列表插件,就必然要获取全国所有城市的信息。全国大概有600多个城市,这么大的数据量难道每次打开这个插件都要去服务器取城市数据吗?这些城市的数据相对非常稳定,并不会频繁变化,每次都去服务器加载是对流量和服务器性能的严重消耗。所以,最好的解决方案就是将城市数据保存在本地缓存中,而不是每次都去服务器请求数据。在一个高性能的产品中,缓存的重要性是不言而喻的。建议开发者将本地缓存视作一个本地的key&value数据库,并封装一些类和公共方法,提供给项目中的各个调用方。最好不要让getStorage、setStorage等方法充斥在项目的每一个角落。Orange Can项目中的DBPost类就是一个不错的示例,它实现了对缓存的良好管理,并向调用方提供了一系列可读性非常强的API。建议开发者参考DBPost并将这种思路应用到自己的项目中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐