上一节我们实现了视频列表展示,接下啦我们需要在上一节的基础之上继续详细解释下当我们点击相应的视频列表图片我们可以跳转到相应的视频播放界面以及显示当前评论消息。效果展示如下

微信小程序项目实战【四】------实现评论+转发+收藏_ide

点击评论按钮跳转到评论界面 

微信小程序项目实战【四】------实现评论+转发+收藏_ico_02

【解析】

通过上面的效果图可知我们要实现这个效果首先要明白我们的数据要保存到那里,我们评论的内容要显示到到当前页面不能我们评论的内容会在所有的页面都能看到,所以我们通过这个分析可以知道我们需要做哪些准备工作。

>首先我们需要将评论中输入的内容当点击发送的时候保存到云数据库

>其次我们需要将我们中的内容显示到视频下面,这里需要使用数据库的基本增删改查语句

>最后就是当我们点击查看更多就是将所有用户在这个视屏下评论的内容全部显示出来,因为使用云开发有个弊端就是一次性只能返回20条记录,这里我们需要使用云函数来帮助我们解决当下疑难。

【代码展示】

//comment.xxml
<view class="fixed-page">
<view class="fixed-cont-body">
<!-- 播放器 -->
<view class="swiper_container">
<view wx:for="{{video}}" wx:for-item="item" class="player">
<video src="{{item.tempFileURL}}" controls></video>
</view>
</view>
<scroll-view wx:for="{{video}}" wx:for-item="item" scroll-y="true" class="main">
<view>
<!-- 诗词信息 -->
<view class="author-box row">
<view class="title">题目:</view>
<view class="author">{{item.title}}</view>
</view>
<!-- 详情描述 -->
<view class="discription-box row">
<view class="title">作者:</view>
<view class="discription">{{item.author}}</view>
</view>
</view>


<!-- 图文信息 -->
<view wx:if="{{comments.length>0}}" class="photo_info_box">
<!-- 图文评论列表 -->
<view class="photo_comment_box">
<text class="photo_comment_title">最新评论</text>
<view wx:for="{{comments}}" wx:for-item="comment" wx:key="index" class="commment_list">
<!-- index < 3 在视频下面只显示三条记录 -->
<view wx:if="{{index < 3}}">
<view class="comment_info">
<view class="c_info_view">
<image src="{{comment.userImage}}"></image>
<text>{{comment.userName}}</text>
</view>
<text class="c_date_txt">{{comment.commitTime}}</text>
</view>
<view class="comment_content">{{comment.content}}</view>
</view>
</view>

<!-- 查看更多评论 -->
<view bindtap="toggleDialogHandle">
<view class="load_more_box">查看更多评论</view>
</view>
</view>
</view>
<view wx:else class="no_comment">
<text class="load_more_box">暂时没有评论!</text>
</view>
</scroll-view>
</view>

<!-- 评论 -->
<view class="comment_fixed_footer">
<view class="footer_oper_box">
<button open-type="share" class="btn">
<image src="/images/share_01.png"></image>
<text>分享</text>
</button>

<view class="footer_c">
<view wx:if="{{collectByMp3IdAndUId.length>0}}">
<image catchtap='_onCollectTap' src="{{isCollected?'/images/no_collect.png':'/images/have_collect.png'}}"></image>
</view>
<view wx:elif="{{collectByMp3IdAndUId.length==0}}">
<image catchtap="onCollectTap" src="{{isCollected?'/images/have_collect.png':'/images/no_collect.png'}}"></image>
</view>
<text>收藏</text>
</view>
</view>

<navigator url="/pages/comment-more/comment-more" open-type="redirect" hover-class="none">
<view class="post_comment_button">
<image src="../../images/icon_comment.png"></image>
<text>评论</text>
</view>
</navigator>
</view>

<!-- 弹出层 -->
<view class="cover_box" wx:if="{{showDialog}}" bindtap="toggleDialogHandle"></view>
<view class="overlay_box" wx:if="{{showDialog}}">
<view class="overlay_title">
<text>评论</text>
<image class="close_btn" src="/images/icon_cancel.png" mode="aspectFill" bindtap="toggleDialogHandle"></image>
</view>
<view wx:for="{{comments}}" wx:for-item="comment">
<view class="comment_info">
<view class="c_info_view">
<image src="{{comment.userImage}}"></image>
<text>{{comment.userName}}</text>
</view>
<text class="c_date_txt">{{comment.commitTime}}</text>
</view>
<view class="comment_content">{{comment.content}}</view>
</view>

</view>

</view>
//comment.wxss
/* 播放器 */

.player video {
width: 100%;
height: 400rpx;
border-radius: 15rpx;
margin-top: 15rpx;
}

/*诗词标题、作者*/

.main {
position: fixed;
left: 0;
top: 425rpx;
right: 750rpx;
bottom: 100rpx;
}

.row {
display: flex;
flex-direction: row;
padding: 0rpx 20rpx 0rpx 20rpx;
margin-top: 20rpx;
}

.title {
display: inline-block;
color: #1f96f2;
margin-right: 10rpx;
font-size: 30rpx;
line-height: 40rpx;
}

.author, .discription, .comment {
flex: 1;
font-size: 30rpx;
line-height: 40rpx;
color: #222;
}

/*诗词信息显示排版*/

.photo_info_box {
padding: 20rpx 50rpx;
}

.author_box {
position: relative;
height: 80rpx;
}

.author_info_view {
width: 45%;
display: flex;
align-items: center;
}

.author_info_view image {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}

.author_info_view text {
margin-left: 20rpx;
}

.author_date_txt {
position: absolute;
right: 0;
color: #999;
height: 37rpx;
top: 22rpx;
}

.photo_summary_txt {
height: 80rpx;
line-height: 40rpx;
margin: 20rpx 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}

.photo_tags_box {
height: 50rpx;
margin-bottom: 20rpx;
}

.tags {
position: relative;
width: 120rpx;
height: 50rpx;
line-height: 50rpx;
margin-right: 25rpx;
text-align: center;
background-color: rgba(0, 0, 0, 0.05);
float: left;
}

.tags::before {
content: '';
position: absolute;
left: 0;
width: 6rpx;
height: 100%;
background-color: #ff5167;
border-top-left-radius: 6rpx;
border-bottom-left-radius: 6rpx;
}

.photo_comment_box {
border-top: 1rpx solid rgb(206, 206, 206);
overflow: hidden;
padding-top: 20rpx;
}

.photo_comment_title {
width: 112rpx;
height: 40rpx;
line-height: 40rpx;
font-size: 30rpx;
}

.comment_info {
position: relative;
height: 60rpx;
margin-top: 20rpx;
}

.c_info_view {
display: flex;
align-items: center;
}

.c_info_view image {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
}

.c_info_view text {
height: 60rpx;
line-height: 60rpx;
margin-left: 20rpx;
}

.c_date_txt {
position: absolute;
right: 0;
top: 12rpx;
height: 37rpx;
line-height: 37rpx;
color: #999;
font-size: 24rpx;
}

.comment_content {
line-height: 40rpx;
margin: 20rpx 0 0 80rpx;
padding-bottom: 30rpx;
border-bottom: 1rpx solid rgb(206, 206, 206);
}

.no_comment {
margin-top: 250rpx;
text-align: center;
}

.load_more_box {
width: 168rpx;
height: 40rpx;
padding: 21rpx 67rpx;
border-radius: 45rpx;
margin: 27rpx auto;
text-align: center;
border: 2rpx solid rgb(206, 206, 206);
}

.comment_fixed_footer {
position: fixed;
bottom: 0;
width: 100%;
height: 110rpx;
background-color: #f5f5f5;
z-index: 1;
}

.footer_oper_box {
width: 58%;
height: 100%;
display: flex;
align-items: center;
}

button::after {
border: none;
}

.btn {
display: flex;
margin-right: 30rpx;
background-color: #f5f5f5;
flex-direction: row;
justify-content: center;
align-items: center;
}

.btn image {
width: 48rpx;
height: 48rpx;

}

.btn text {
margin-left: 30rpx;
font-size: 36rpx;
color: #333;
}

.footer_c {
display: flex;
margin-right: 15rpx;
}

.footer_c image {
width: 48rpx;
height: 48rpx;
margin-right: 15rpx;
}

.footer_c text {
margin-right: 15rpx;
font-size: 36rpx;
color: #333;
}

.post_comment_button {
width: 42%;
height: 100%;
position: absolute;
right: 0;
bottom: 0;
background-color: #ff5167;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
}

.post_comment_button image {
width: 64rpx;
height: 64rpx;
}

.post_comment_button text {
color: snow;
margin-left: 14rpx;
font-size: 36rpx;
}

/* 查看更多评论 */

.cover_box {
position: fixed;
width: 100%;
height: 100%;
z-index: 2;
background-color: rgba(0, 0, 0, 0.5);
top: 0;
left: 0;
}

.overlay_box {
position: fixed;
width: 100%;
box-sizing: border-box;
z-index: 3;
padding: 30rpx 40rpx;
height: 800rpx;
background-color: #f5f5f5;
bottom: 0;
overflow: scroll;
}

.overlay_title {
position: relative;
height: 48rpx;
}

.overlay_title text {
font-size: 34rpx;
}

.overlay_title image {
position: absolute;
right: 0;
width: 36rpx;
height: 36rpx;
top: 6rpx;
}

.textarea_box {
height: 213rpx;
border-radius: 10rpx;
border: 1rpx solid rgb(206, 206, 206);
margin-top: 30rpx;
overflow: hidden;
}
//comment.js
var app = getApp();
var util = require('../util/util.js');
Page({

data: {
showDialog: false,
video:[],
collect:[],
isCollected:false,
collectByMp3IdAndUId:[]
},

onLoad: function(options) {
this.showAllComment();
this.showVideo();
this.getCollectByMp3IdAndUId(app.requestDetailid, app.globalData.openid);
},

//打开评论弹出层
toggleDialogHandle: function() {
this.showDialog = !this.showDialog;
this.setData({
showDialog: this.showDialog
})
},

// 把用户输入的评论保存到变量里
bindNewComment: function(e) {
this.data.newComment = e.detail.value; // 不更新 input,提高效率
},
//提交评论
submitComment() {
var that = this
// 如果评论输入为空,则提示用户输入,不进行提交
if (!this.data.newComment) {
wx.showToast({
title: '请输入评论'
});
} else {
that.addComment();
}
},
//添加评论
addComment() {
const db = wx.cloud.database() //打开数据库连接
var videoId = getApp().requestDetailid; //获取当前videoId
var time = util.formatTime(new Date()) // 获取当地时间
db.collection("comments").add({
data: {
userName: app.globalData.userInfo.nickName,
userImage: app.globalData.userInfo.avatarUrl,
content: that.data.newComment,
commitTime: time,
videoId: videoId
},

success: res => {
wx.showToast({
title: '评论成功',
})
this.setData({
newComment: ''
})

wx.navigateTo({
url: '../comment/comment',
})
},
fail: err => {
wx.showToast({
title: '评论失败',
})
}
})

},
//查询所有评论
showAllComment() {
/*const db = wx.cloud.database()
//接收从welcome.js传递过来的id
var videoId = getApp().requestDetailid;
db.collection("comments").where({
videoId: videoId
}).get({
success: res => {
this.setData({
comments: res.data,
})
},
fail: err => {
wx.showToast({
icon: "none",
title: '查询评论失败',
})
}
})*/
var videoId = getApp().requestDetailid;
wx.cloud.callFunction({
name: 'show',
data: {
videoId: {videoId}
}
}).then(res => {
this.setData({
comments: res.result.data,
})
})



},
//显示视频
showVideo() {
let that = this;
var videoId = getApp().requestDetailid;
const db = wx.cloud.database()
db.collection("videos").where({
videoId: videoId
}).get({
success: res => {
that.setData({
video: res.data,
})
console.log(res.data)
},
fail: err => {
wx.showToast({
icon: "none",
title: '播放失败',
})
}
})
},
//分享转发
onShareAppMessage: function () {
let that = this;
return {
title: this.data.video[0].title,
videoImg: that.data.video[0].videoImg,
success: function (res) {
// 转发成功
console.log('转发成功!')
},
fail: function (res) {
// 转发失败
console.log('转发失败!')
}
}
},
//收藏与未收藏之间的转换
onCollectTap(){
var isCollected = this.data.isCollected;
if (isCollected) {
//取消收藏
var videoId = getApp().requestDetailid;
var user_oppenId = app.globalData.openid;//此为当前用户的oppenId
console.log('-----测试-------' + user_oppenId);
this.removeCollect(videoId, user_oppenId);
// 设置setData值,前端界面才能读取到isCollect的值,以下同理
this.setData({
isCollected: false
})
} else {
//收藏
this.addCollect();
this.setData({
isCollected: true
})
}

},
_onCollectTap(){
var isCollect = this.data.isCollect;
if (isCollect) {
//收藏
this.addCollect();
this.setData({
isCollected: false
})
} else {
//取消收藏
var videoId = getApp().requestDetailid;
var user_oppenId = app.globalData.openid;//此为当前用户的oppenId
this.removeCollect(videoId, user_oppenId);
// 设置setData值,前端界面才能读取到isCollect
this.setData({
isCollected: true
})
}
},
//收藏
addCollect(){
let that = this;
const db = wx.cloud.database() //打开数据库连接
var videoId = getApp().requestDetailid; //获取当前videoId
db.collection("collects").add({
data: {
title:this.data.video[0].title,
author: this.data.video[0].author,
tempFileURL: that.data.video[0].tempFileURL,
videoImg: that.data.video[0].videoImg,
videoId: videoId,
},
success: res => {
wx.showToast({
title: "收藏成功",
icon: 'success',
duration: 1000,
make: true
});
},
fail: err => {
wx.showToast({
title: "服务器维护中,收藏失败",
duration: 1000,
icon: "sucess",
make: true
})
}

})



},
//删除收藏信息,根据视频id和用户id指定唯一的收藏信息
removeCollect: function (videoId, user_openid) {
const db = wx.cloud.database();
db.collection("collects").where({
videoId: videoId,
_openid: user_openid
}).get({
success: res => {
db.collection("collects").doc(res.data[0]._id).remove({
success: res => {
wx.showToast({
title: '已取消收藏',
})
}, fail: err => {
wx.showToast({
title: '取消失败',
})
}
})
},
fail: err => {
wx.showToast({
icon: "none",
title: '查询记录失败',
})
}
})
},

//根据视频id和用户oppenId获取收藏信息
getCollectByMp3IdAndUId: function (videoId, user_openid) {
var user_openid = app.globalData.openid;
var videoId = getApp().requestDetailid;
const db = wx.cloud.database()
db.collection("collects").where({
videoId: videoId,
_openid: user_openid,
}).get({
success: res => {
var that = this
that.setData({
collectByMp3IdAndUId: res.data,
})
, console.log('---------->>>' + res.data)
console.log('---------->>>' + app.globalData.openid)
},
fail: err => {
wx.showToast({
icon: "none",
title: '服务器维护中',
})
}
})
},

})

这下面的是点击评论跳转到评论界面的界面代码

//comment-more.xml
<view>
<!-- 输入评论 -->
<view class="textarea_box">
<textarea value="{{newComment}}" bindinput="bindNewComment" placeholder="写下您的评论" name="textarea" />
</view>
<view class="input-box">
<button bindtap="submitComment" type="default" plain="{{true}}" class="send_btn">发送</button>
</view>
</view>
//comment-more.wxss
.textarea_box {
padding: 30rpx 40rpx;
height: 280rpx;
border-radius: 10rpx;
border: 0rpx solid #f5f5f5;
margin-top: 20rpx;
overflow: hidden;
}

.input-box {
display: flex;
justify-content: center;
align-items: center;
}

.send_btn {
color: snow;
padding: 10rpx 100rpx;
border-radius: 70rpx;
background-color: #ff5167;
display: inline-block;
vertical-align: top;
text-align: center;
margin-top: 40rpx;
font-size: 12px;
}
//comment-more.js
var app = getApp();
var util = require('../util/util.js');
Page({

/**
* 页面的初始数据
*/
data: {

},

onLoad: function (options) {
const db = wx.cloud.database()
//接收从welcome.js传递过来的id
var videoId = getApp().requestDetailid;



},
// 把用户输入的评论保存到变量里
bindNewComment: function(e) {
this.data.newComment = e.detail.value; // 不更新 input,提高效率
},
//提交评论并保存到云数据库中
submitComment() {
const db = wx.cloud.database() //打开数据库连接
var videoId = getApp().requestDetailid; //获取当前videoId
var that = this
// 获取当地时间
var time = util.formatTime(new Date())
// 如果评论输入为空,则提示用户输入,不进行提交
if (!this.data.newComment) {
wx.showToast({
title: '请输入评论'
});
} else {

db.collection("comments").add({
data: {
userName: app.globalData.userInfo.nickName,
userImage: app.globalData.userInfo.avatarUrl,
content: that.data.newComment,
commitTime: time,
videoId: videoId
},

success: res => {
wx.showToast({
title: '评论成功',
})
this.setData({
newComment: ''
})

wx.navigateTo({
url: '../comment/comment'
})
},
fail: err => {
wx.showToast({
title: '评论失败',
})
}
})
}
}
})

【总结】

以上就是评论+转发+收藏的基本代码,注释的也是很清楚,如果有什么不懂的请留言我会及时回复给大家