Vue.js實(shí)現(xiàn)文章評(píng)論和回復(fù)評(píng)論功能
本來(lái)想把這個(gè)頁(yè)面用jade渲染出來(lái)、評(píng)論部分用vue,但是想了想覺(jué)得麻煩,最后還是整個(gè)用vue的組件搞定他吧。
先上在線demo:http://jsbin.com/ceqifo/1/edit?js,output
再上效果圖
可直接評(píng)論,點(diǎn)擊別人的評(píng)論能回復(fù)別人的評(píng)論。
html
<div id="comment"> <article-content v-bind:article="article"></article-content> <commemt-content v-bind:comment="comment" v-on:change="changCommmer"></commemt-content> <comment-textarea v-bind:type="type" v-bind:name="oldComment" v-on:submit="addComment" v-on:canel="canelCommit"></comment-textarea> </div>
數(shù)據(jù)全都由根組件綁定下去的。這里還監(jiān)聽(tīng)了幾個(gè)事件。
<article-content是文章內(nèi)容的組件,沒(méi)啥好講的,直接把數(shù)據(jù)綁定進(jìn)去子組件就行了。這里我是直接綁定一個(gè)obj而不是把標(biāo)題、時(shí)間等等詳細(xì)的信息分別綁定進(jìn)去。因?yàn)橹苯咏壎ㄒ粋€(gè)對(duì)象,子組件可以用.的方式很好的調(diào)用,比分開(kāi)寫好多了。
<article-content組件–文本
然后先說(shuō)個(gè)簡(jiǎn)單點(diǎn)的,<comment-textarea>,文本框的那個(gè)組件。
Vue.component('commentTextarea',{ template:'\ <div class="commentBox">\ <h3>發(fā)表評(píng)論</h3>\ <b v-if="type">你回復(fù) {{name}}</b>\ <textarea name="" value="請(qǐng)?zhí)顚懺u(píng)論內(nèi)容" v-model="commentText"></textarea>\ <button class="btn" @click="addComment">發(fā)表</button>\ <button class="btn" @click="canelComment">取消</button>\ </div>', props: ['type','name'], data: function(){ return {commentText:""} }, methods: { addComment: function() { this.$emit("submit",this.commentText); this.commentText = ""; }, canelComment: function() { this.$emit("canel"); this.commentText = ""; } } });
type是如果點(diǎn)擊了別人的評(píng)論,會(huì)顯示 ”你回復(fù)xxx “ 的提示框,這個(gè)因?yàn)榭缌私M件通信而且兩組件不是父子組件但是是兄弟組件,我把他們的通信掛在了父組件的一個(gè)屬性上,實(shí)現(xiàn)通信。
文本框內(nèi)的內(nèi)容用一個(gè)v-model雙向綁定,如果點(diǎn)擊了確定,就觸發(fā)一個(gè) addComment事件并把文本內(nèi)容傳給父組件,父組件會(huì)監(jiān)聽(tīng)事件。
commemt-content組件–評(píng)論內(nèi)容
先來(lái)確定json格式
comment: [ { name: "有毒的黃同學(xué)", //評(píng)論人名字 time: "2016-08-17", content: "好,講得非常好,good", reply: [ //回復(fù)評(píng)論的信息,是一個(gè)數(shù)組,如果沒(méi)內(nèi)容就是一個(gè)空數(shù)組 { responder: "傲嬌的", //評(píng)論者 reviewers: "有毒的黃同學(xué)", //被評(píng)論者 time: "2016-09-05", content: "你說(shuō)得對(duì)" } } ]
再來(lái)看commemt-content組件
Vue.component('commemt-content',{ template:'\ <div class="commentBox">\ <h3>評(píng)論</h3>\ <p v-if="comment.length==0">暫無(wú)評(píng)論,我來(lái)發(fā)表第一篇評(píng)論!</p>\ <div v-else>\ <div class="comment" v-for="(item,index) in comment" v-bind:index="index" >\ <b>{{item.name}}<span>{{item.time}}</span></b>\ <p @click="changeCommenter(item.name,index)">{{item.content}}</p>\ <div v-if="item.reply.length > 0">\ <div class="reply" v-for="reply in item.reply">\ <b>{{reply.responder}} 回復(fù) {{reply.reviewers}}<span>{{reply.time}}</span></b>\ <p @click="changeCommenter(reply.responder,index)"">{{reply.content}}</p>\ </div>\ </div>\ </div>\ </div>\ </div>', props: ['comment'], methods: { changeCommenter: function(name,index) { this.$emit("change",name,index); } } });
如果沒(méi)有內(nèi)容,則顯示 “暫無(wú)評(píng)論,我來(lái)發(fā)表第一篇評(píng)論!”。如果有內(nèi)容就開(kāi)始遍歷。因?yàn)辄c(diǎn)擊評(píng)論要知道第幾條,所以每條評(píng)論要綁一個(gè)v-bind:index="index"
到了二次評(píng)論那塊,還是遍歷reply數(shù)組,綁定該綁定的。因?yàn)榫退泓c(diǎn)擊內(nèi)容,也是加到那條一級(jí)評(píng)論的最下面,所以兩個(gè)點(diǎn)擊事件我都是綁定了同一個(gè)事件。只是傳進(jìn)去的名字不一樣而已,后面那個(gè)index都是一級(jí)評(píng)論的index。
changeCommenter事件觸發(fā)了change,父組件監(jiān)聽(tīng),執(zhí)行相應(yīng)行為。
父組件
var comment = new Vue({ el: "#comment", data: { commenter: "session", //評(píng)論人,這里會(huì)從session拿 type: 0, //0為評(píng)論作者1為評(píng)論別人的評(píng)論 oldComment: null, //久評(píng)論者的名字 chosedIndex: -1, //被選中的評(píng)論的index article: { title: "當(dāng)歸泡水喝的九大功效", time: "2016-07-12", read:50, content: "" }, comment: [] //評(píng)論內(nèi)容 }, methods: { //添加評(píng)論 addComment: function(data) { if(this.type == 0) { this.comment.push({ name: 'session', time: getTime(), content: data, reply: [] }); //服務(wù)器端 }else if(this.type == 1){ this.comment[this.chosedIndex].reply.push({ responder: 'session', reviewers:this.comment[this.chosedIndex].name, time: getTime(), content: data }); this.type = 0; } }, //監(jiān)聽(tīng)到了點(diǎn)擊了別人的評(píng)論 changCommmer: function(name,index) { this.oldComment = name; this.chosedIndex = index; this.type = 1; }, //監(jiān)聽(tīng)到了取消評(píng)論 canelCommit: function() { this.type = 0; } } })
data那里。。。實(shí)在是取名困難癥啊。。。commenter是當(dāng)前登錄名,這里到時(shí)候會(huì)session里拿;type就是看到底是評(píng)論作者的還是評(píng)論別人的評(píng)論的;oldComment就是就評(píng)論者的名字(實(shí)際儲(chǔ)存的時(shí)候應(yīng)該是id);chosedIndex是被點(diǎn)擊的評(píng)論的index。
canelCommit是監(jiān)聽(tīng)到取消評(píng)論事件,這里是為了如果了點(diǎn)擊了別人的評(píng)論但是突然我就是想變?cè)u(píng)論作者用的。所以設(shè)type=0;
changCommmer是監(jiān)聽(tīng)到點(diǎn)擊了別人評(píng)論想回復(fù)評(píng)論的。即type=1.
addComment就是監(jiān)聽(tīng)添加評(píng)論事件的。根據(jù)type的值,push相應(yīng)的數(shù)組。這里還要記得跟數(shù)據(jù)庫(kù)那個(gè)對(duì)接。傳數(shù)據(jù)有兩種方法,這里是根據(jù)type的不同分兩個(gè)url傳還是一個(gè),取決于表的設(shè)計(jì)。待我明天好好設(shè)計(jì)表后,加入http請(qǐng)求,完成這個(gè)評(píng)論功能。
要期末了。真的怕掛科。
補(bǔ)充一下:
由于第一次自己設(shè)計(jì)數(shù)據(jù)庫(kù)的表結(jié)構(gòu),所以很有問(wèn)題。
更新一下,正確的表結(jié)構(gòu)應(yīng)該是每條評(píng)論都有自己的id,有一個(gè)parentId屬性默認(rèn)為null,如果是直接評(píng)論的話,parentId值為null,如果是回復(fù)別人的評(píng)論的話,parentId是那條評(píng)論的id。最后查出一條條數(shù)據(jù)后,再根據(jù)里面的是否有parentId等再組件這個(gè)obj,傳到前端。如果直接組這個(gè)obj的話會(huì)for循環(huán)3次,所以。。。打算用一用數(shù)據(jù)結(jié)構(gòu)里的散列,不用for循環(huán)這么多次。這周末搞定這個(gè),下篇文章就是它了。
然而當(dāng)我思考了下后。如果單單用散列的話,就不能根據(jù)時(shí)間來(lái)排序了。因?yàn)樯⒘惺歉鶕?jù)id%length的值來(lái)插入的,所以沒(méi)了時(shí)間排序。如果直接根據(jù)查數(shù)據(jù)庫(kù)返回的數(shù)組組合這個(gè)obj的話,肯定是早插入的id靠前所以有時(shí)間順序。這個(gè)數(shù)據(jù)結(jié)構(gòu)的問(wèn)題還真不簡(jiǎn)單啊。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue實(shí)現(xiàn)發(fā)表評(píng)論功能
- vue實(shí)現(xiàn)文章評(píng)論和回復(fù)列表
- VUE+Java實(shí)現(xiàn)評(píng)論回復(fù)功能
- Vue組件實(shí)現(xiàn)評(píng)論區(qū)功能
- vue開(kāi)發(fā)實(shí)現(xiàn)評(píng)論列表
- vue實(shí)現(xiàn)評(píng)論列表
- Vue實(shí)現(xiàn)簡(jiǎn)單的發(fā)表評(píng)論功能
- vue實(shí)現(xiàn)評(píng)論列表功能
- Vuepress 搭建帶評(píng)論功能的靜態(tài)博客的實(shí)現(xiàn)
- vue組件實(shí)現(xiàn)發(fā)表評(píng)論功能
相關(guān)文章
Vue2 SSR渲染根據(jù)不同頁(yè)面修改 meta
本篇文章主要介紹了Vue2 SSR渲染根據(jù)不同頁(yè)面修改 meta,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11element el-tooltip動(dòng)態(tài)顯示隱藏(有省略號(hào)顯示,沒(méi)有省略號(hào)不顯示)
本文主要介紹了element el-tooltip動(dòng)態(tài)顯示隱藏,主要實(shí)現(xiàn)有省略號(hào)顯示,沒(méi)有省略號(hào)不顯示,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09Element 默認(rèn)勾選表格 toggleRowSelection的實(shí)現(xiàn)
這篇文章主要介紹了Element 默認(rèn)勾選表格 toggleRowSelection的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09vue如何將html內(nèi)容轉(zhuǎn)為圖片并下載到本地
這篇文章主要介紹了vue如何將html內(nèi)容轉(zhuǎn)為圖片并下載到本地,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01Vue自定義省市區(qū)三級(jí)聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了Vue自定義省市區(qū)三級(jí)聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03vue3實(shí)現(xiàn)模擬地圖站點(diǎn)名稱按需顯示的功能(車輛模擬地圖)
最近在做車輛模擬地圖,在實(shí)現(xiàn)控制站點(diǎn)名稱按需顯示,下面通過(guò)本文給大家分享vue3實(shí)現(xiàn)模擬地圖站點(diǎn)名稱按需顯示的功能,感興趣的朋友跟隨小編一起看看吧2024-06-06詳解利用eventemitter2實(shí)現(xiàn)Vue組件通信
這篇文章主要介紹了詳解利用eventemitter2實(shí)現(xiàn)Vue組件通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11