打開評論彈窗,input
框獲取焦點,input
框默認提示文字爲留下你精彩的評論吧
,輸入內容點擊提交
,便可向服務器發送請求,並將評論內容,評論時間,用戶頭像,用戶暱稱
等內容在頁面進行渲染。javascript
點擊用戶評論,input
框獲取焦點,修改input
框的默認提示文字爲回覆 @被回覆用戶的暱稱
,點擊提交後,剩餘操做與1
相同。css
用戶提交評論前,須要作校驗,評論內容
不能爲空,用戶須要登陸
後才能評論。html
評論提交按鈕默認是灰色,處於disable
狀態;當評論內容不爲空時,提交按鈕樣式發生變化,狀態也變爲enable
狀態。前端
評論是能夠被回覆和點讚的。由於回覆也能夠看作是一條評論,爲了區別是評論仍是回覆,咱們爲評論對象設計了father_comment_id
。同時,爲了區分這個評論是回覆誰的,咱們爲評論對象設計了to_user_id
。vue
import axios from 'axios'
import {BASE_URL} from './route'
export function sendComment(params){
return axios.post(`${BASE_URL}/saveComment`,params)
}
複製代碼
目前先實現評論發送功能,對評論展現暫時先放在一邊。因此,咱們只要處理input
框的樣式和邏輯。(css
樣式會在文章最後完整代碼給出。)java
<div class="comment_input_box_hover"></div>
<div class="comment_input_box" v-show="commentPop"> //commentPop用來控制是否顯示評論彈窗
<input
:placeholder="commentPlaceholder" //placeholder綁定data中的commentPlaceHolder,實現咱們的需求
class="comment_input"
v-model="comment_text"
ref="content"
@click="checkComment"
/>
<div class="comment_input_right" @click="checkComment"> <i class="iconfont icon-fasong comment_i" :class="canSend?'comment_i_active':''"></i> // canSend用來標識評論是否能夠發送。 </div>
複製代碼
data
和methods
data(){
commentPlaceholder:'留下你精彩的評論吧',
comment_text:'', // 評論內容,由v-model實現雙向綁定
hasSend:false, // 標識評論是否已經發送過,防止同一條評論被重複提交
canSend:false, //canSend用來標識評論是否能夠發送
video_id:'',// 標識是哪個視頻的評論
to_user_id:'',// 須要回覆對象的id
father_comment_id:'',// 父評論的id
}
methods:{
// 在發送評論以前,咱們須要對輸入的內容作合法性判段
checkComment() {
if (this.comment_text == "") {
Toast("評論內容不能爲空");
} else {
if (!this.isLogin) {
this.$router.push({
path: "/login"
});
return;
}
const to_user_id = this.to_user_id;
const father_comment_id = this.father_comment_id;
const comment = this.comment_text;
const video_id = this.video_id;
const id = Date.now();
const newComment = {
avatar: this.userInfo.avatar,
comment,
id,
create_time: "剛剛",
nickname: this.userInfo.nickname
};
sendComment({ to_user_id, father_comment_id, comment, video_id }).then(
val => {
this.comment_text = "";
this.hasSend = true;
this.commentList.unshift(newComment);
}
);
}
},
}
watch:{
comment_text(newVal,oldVal){ // 監聽comment_text的變化,動態修改提交按鈕的樣式和狀態
this.canSend = newVal ==='' ? true:false
}
}
複製代碼
注意,video_id
是在打開評論彈窗時獲取並賦值的,這裏並無涉及到評論彈窗的打開與關閉操做,所以直接省略了video_id的賦值操做ios
changeComments(item) {
if (this.showShareBox) {
// 打開評論彈窗以前,要先關閉分享彈窗
this.commentPop = false;
}
this.commentPop = true;
this.video_id = item.id // 對video_id進行了賦值操做
// 打開評論窗時須要從服務端獲取評論列表
getCommentList(this.video_id).then(val => {
let data = val.data.message;
data.forEach(item => {
});
this.commentList = data;
});
},
複製代碼
<van-popup v-model="commentPop" :overlay="true" class="comment_container" position="bottom">
<div class="comment_box">
<div class="comment_top">
{{commentList.length}}條評論
<i
class="iconfont icon-guanbi1 guanbi3"
@click="closeCommentsBox"
></i>
</div>
<ul class="comment_ul">
<div v-if="commentList.length!=0">
<transition-group appear>
<li
class="comment_li"
v-for="(item,index) in commentList"
:key="item.id"
@click="replyUser(item,index,-1)" <!-- 在這裏爲每條評論綁定了點擊事件-->
>
<div class="comment_author_left">
<img :src="item.avatar" />
</div>
<div class="comment_author_right">
<div class="comment_author_top">
<div class="comment_author_name">@{{item.nickname}}</div>
<div class="icon-shoucang1_box" @click.stop="commentLove(item,index,-1)">
<div class="icon_right_change" :class="item.love_comment?'love_active':''">
<i class="iconfont icon-shoucang1"></i>
</div>
<div class="shoucang1_num">{{item.love_count}}</div>
</div>
</div>
<div class="comment_author_text">
{{item.comment}}
<span>{{item.create_time}}</span>
</div>
</div>
<div class="clear"></div>
<div class="comment_reply_box">
<transition-group appear>
<div
class="comment_reply_li"
v-for="(item2,index2) in item.child_comment"
:key="item2"
@click.stop="replyUser(item2,index,index2)"
>
<div class="comment_reply_left">
<img :src="item2.avatar" />
</div>
<div class="comment_reply_right">
<div class="comment_reply_top">
<div class="comment_reply_name">@{{item2.nickname}}</div>
<div
class="icon-shoucang1_box"
@click.stop="commentLove(item2,index,index2)"
>
<div
class="icon_right_change"
:class="item2.love_comment?'love_active':''"
>
<i class="iconfont icon-shoucang1"></i>
</div>
<div class="shoucang1_num">{{item2.love_count}}</div>
</div>
</div>
<div class="comment_reply_text">
<span
v-if="item.user_id!=item2.be_commented_user_id && item.user_id!=item2.user_id"
>
回覆
{{item2.be_commented_nickname}}:
</span>
{{item2.comment_content}}
<span>{{item2.create_time}}</span>
</div>
</div>
<div class="clear"></div>
</div>
</transition-group>
</div>
</li>
</transition-group>
</div>
<div class="no_message" v-if="!commentList.length">
<i class="iconfont iconfont_style icon-zanwupinglun"></i>
<div class="no_message_tips">暫無評論</div>
</div>
</ul>
</div>
</van-popup>
複製代碼
打開評論彈窗時,發起獲取評論的請求vuex
methods:{
changeComments(item) {
if (this.showShareBox) {
// 打開評論彈窗以前,要先關閉分享彈窗
this.commentPop = false;
}
this.commentPop = true;
this.video_id = item.id
getCommentList(this.video_id).then(val => {
this.commentList = val.data.message;
this.commentList.forEach((item)=>{
item.create_time = formatTime(new Date(item.create_time))
})
});
},
}
複製代碼
在前面,已經實現了評論功能,但新發表的評論並無在頁面中顯示出來,只有在刷新頁面後纔會顯示。爲了解決這個問題,咱們須要在發送評論以後,將新評論封裝成一個對象,而後插入到commentList
中。越新的評論放在越前面,也就是新評論應該放在第一個位置。因此新評論應該插入到commentList
中的0號位置。數據庫
如何構建新的評論對象
在頁面顯示時,須要顯示的內容有nickname
,avatar
,comment
,create_time
,另外,由於在遍歷過程當中是使用item.id
來綁定:key
的。所以咱們須要一個爲這個對象綁定一個id
,其實這個id
只是起臨時做用,並不會寫到數據庫。爲了保證id的惟一性,咱們經過Date.now()
來生成這個id
。而其餘字段的內容,咱們能夠經過在vuex
中,或者上下文中取到。
因此構建出來的comment
長成下面這個樣子:axios
const id = Date.now()
const comment = this.comment_text;
const newComment = {
avatar:this.userInfo.avatar,
comment,
id,
create_time:'剛剛',
nickname:this.userInfo.nickname,
}
複製代碼
此外,還須要修改一下咱們的sendComment
以後的邏輯,就是將新的評論對象插到commentList
中去。
sendComment({ to_user_id, father_comment_id, comment, video_id }).then(
val => {
this.comment_text = "";
this.hasSend = true;
this.commentList.unshift(newComment) //將新的評論對象插入到數組中去
}
);
複製代碼
vue
前端部分的評論功能已經實現,接下來就是回覆功能了...