用vuejs實作評論功能的方法:1、使用article-content元件,綁定一個obj;2、透過commemt-content元件實現評論功能即可。
本文操作環境:windows7系統、vue2.9.6版,DELL G3電腦。
怎麼用vuejs實作註解功能?
Vue.js實作文章註解並回覆留言功能:
本來想把這個頁面用jade渲染出來、留言部分用vue,但想了想覺得麻煩,最後還是整個用vue的元件搞定他吧。
先上線上demo:http://jsbin.com/ceqifo/1/edit?js,output
再上效果圖
可直接評論,點擊別人的評論能回覆別人的評論。
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>
資料全都由根元件綁定下去的。這裡還監聽了幾個事件。
cb54d79c386a8e44927f3dc3b67ec849,文字方塊的那個元件。
Vue.component('commentTextarea',{ template:'\ <div class="commentBox">\ <h3>发表评论</h3>\ <b v-if="type">你回复 {{name}}</b>\ <textarea name="" value="请填写评论内容" v-model="commentText"></textarea>\ <button class="btn" @click="addComment">发表</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是如果點擊了別人的評論,會顯示”你回复xxx “ 的提示框,這個因為跨了組件通信而且兩組件不是父子組件但是是兄弟組件,我把他們的通信掛在了父元件的一個屬性上,實作通訊。
文字方塊內的內容用v-model雙向綁定,如果點擊了確定,就觸發一個 addComment事件並把文字內容傳給父元件,父元件會監聽事件。
commemt-content元件–評論內容
先來確定json格式
comment: [ { name: "有毒的黄同学", //评论人名字 time: "2016-08-17", content: "好,讲得非常好,good", reply: [ //回复评论的信息,是一个数组,如果没内容就是一个空数组 { responder: "傲娇的", //评论者 reviewers: "有毒的黄同学", //被评论者 time: "2016-09-05", content: "你说得对" } } ]
再來看commemt-content元件
Vue.component('commemt-content',{ template:'\ <div class="commentBox">\ <h3>评论</h3>\ <p v-if="comment.length==0">暂无评论,我来发表第一篇评论!</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}} 回复 {{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); } } });
如果沒有內容,則顯示「暫無評論,我來發表第一篇評論!」。如果有內容就開始遍歷。因為點擊評論要知道第幾條,所以每個評論要綁一個v-bind:index="index"
#到了二次評論那塊,還是遍歷reply數組,綁定該綁定的。因為就算點擊內容,也是加到那一級評論的最下面,所以兩個點擊事件我都是綁定了同一個事件。只是傳進去的名字不一樣而已,後面那個index都是一級評論的index。
changeCommenter事件觸發了change,父元件監聽,執行對應行為。
父元件
var comment = new Vue({ el: "#comment", data: { commenter: "session", //评论人,这里会从session拿 type: 0, //0为评论作者1为评论别人的评论 oldComment: null, //久评论者的名字 chosedIndex: -1, //被选中的评论的index article: { title: "当归泡水喝的九大功效", time: "2016-07-12", read:50, content: "" }, comment: [] //评论内容 }, methods: { //添加评论 addComment: function(data) { if(this.type == 0) { this.comment.push({ name: 'session', time: getTime(), content: data, reply: [] }); //服务器端 }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; } }, //监听到了点击了别人的评论 changCommmer: function(name,index) { this.oldComment = name; this.chosedIndex = index; this.type = 1; }, //监听到了取消评论 canelCommit: function() { this.type = 0; } } })
data那裡。 。 。實在是取名困難症啊。 。 。 commenter是目前登入名,這裡到時候會session裡拿;type就是看到底是評論作者的還是評論別人的評論的;oldComment就是就評論者的名字(實際儲存的時候應該是id);chosedIndex是被點擊的評論的index。
canelCommit是監聽到取消評論事件,這裡是為瞭如果了點擊了別人的評論但是突然我就是想變評論作者用的。所以設type=0;
changCommmer是監聽到點擊了別人評論想回覆評論的。即type=1.
addComment就是監聽加入評論事件的。根據type的值,push對應的陣列。這裡還要記得跟資料庫那個對接。傳資料有兩種方法,這裡是根據type的不同分兩個url傳還是一個,取決於表格的設計。待我明天好好設計表格後,加入http請求,完成這個評論功能。
要期末了。真的怕掛科。
補充:
由於第一次自己設計資料庫的表格結構,所以很有問題。
更新一下,正確的表結構應該是每個評論都有自己的id,有一個parentId屬性預設為null,如果是直接評論的話,parentId值為null,如果是回覆別人的評論的話,parentId是那條評論的id。最後查出一條資料後,再根據裡面的是否有parentId等再組件這個obj,傳到前端。如果直接組這個obj的話會for循環3次,所以。 。 。打算用一用資料結構裡的雜湊,不用for迴圈這麼多次。這週末搞定這個,下篇文章就是它了。
然而當我思考了下後。如果單單用散列的話,就不能依時間來排序了。因為散列是根據id%length的值來插入的,所以沒了時間排序。如果直接依照查資料庫傳回的陣列組合這個obj的話,一定是早插入的id前面所以有時間順序。這個資料結構的問題還真不簡單。
推薦:《最新的5個vue.js影片教學精選》
以上是怎麼用vuejs實現評論功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!