前言
这两天在用vue重构之前写的一个社区博客项目,之前评论的样式和效果都差强人意,所以仿照掘金重写了一个评论功能(但不是完全照搬模仿)
在写完这个功能后,由心觉得Vue真的非常好用。
话不多说,先上效果图
代码
html代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | < div > < div class = "my-reply" > < div class = "reply-info" > < div id = "replyInput" class = "reply-input" > </ div > </ div > < div class = "reply-btn-box" > 发表评论 </ div > </ div > < div class = "author-title reply-father" > < div class = "author-info" > < span class = "author-name" >{{item.name}}</ span > < span class = "author-time" >{{item.time}}</ span > </ div > < div class = "icon-btn" > < span >< i class = "iconfont el-icon-s-comment" ></ i >{{item.commentNum}}</ span > < i class = "iconfont el-icon-caret-top" ></ i >{{item.like}} </ div > < div class = "talk-box" > < p > < span class = "reply" >{{item.comment}}</ span > </ p > </ div > < div class = "reply-box" > < div class = "author-title" > < div class = "author-info" > < span class = "author-name" >{{reply.from}}</ span > < span class = "author-time" >{{reply.time}}</ span > </ div > < div class = "icon-btn" > < span >< i class = "iconfont el-icon-s-comment" ></ i >{{reply.commentNum}}</ span > < i class = "iconfont el-icon-caret-top" ></ i >{{reply.like}} </ div > < div class = "talk-box" > < p > < span >回复 {{reply.to}}:</ span > < span class = "reply" >{{reply.comment}}</ span > </ p > </ div > < div class = "reply-box" > </ div > </ div > </ div > < div class = "my-reply my-comment-reply" > < div class = "reply-info" > < div class = "reply-input reply-comment-input" ></ div > </ div > < div class = " reply-btn-box" > 发表评论 </ div > </ div > </ div > </ div > |
JS代码如下
我把模拟的数据写在了data里面,显得js有点长。如果要更改数据的格式的话,记得也要改Html不然会出错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | const clickoutside = { // 初始化指令 bind(el, binding, vnode) { function documentHandler(e) { // 这里判断点击的元素是否是本身,是本身,则返回 if (el.contains(e.target)) { return false ; } // 判断指令中是否绑定了函数 if (binding.expression) { // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法 binding.value(e); } } // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听 el.vueClickOutside = documentHandler; document.addEventListener( 'click' , documentHandler); }, update() {}, unbind(el, binding) { // 解除事件监听 document.removeEventListener( 'click' , el.vueClickOutside); delete el.vueClickOutside; }, }; export default { name: 'ArticleComment' , data(){ return { btnShow: false , index: '0' , replyComment: '' , myName: 'Lana Del Rey' , myId:19870621, to: '' , toId:-1, comments:[ { name: 'Lana Del Rey' , id:19870621, comment: '我发布一张新专辑Norman Fucking Rockwell,大家快来听啊' , time: '2019年9月16日 18:43' , commentNum:2, like:15, inputShow: false , reply:[ { from: 'Taylor Swift' , fromId:19891221, to: 'Lana Del Rey' , toId:19870621, comment: '我很喜欢你的新专辑!!' , time: '2019年9月16日 18:43' , commentNum:1, like:15, inputShow: false }, { from: 'Ariana Grande' , fromId:1123, to: 'Lana Del Rey' , toId:19870621, comment: '别忘记宣传我们的合作单曲啊' , time: '2019年9月16日 18:43' , commentNum:0, like:5, inputShow: false } ] }, { name: 'Taylor Swift' , id:19891221, comment: '我发行了我的新专辑Lover' , time: '2019年9月16日 18:43' , commentNum:1, like:5, inputShow: false , reply:[ { from: 'Lana Del Rey' , fromId:19870621, to: 'Taylor Swift' , toId:19891221, comment: '新专辑和speak now 一样棒!' , time: '2019年9月16日 18:43' , commentNum:25, like:5, inputShow: false } ] }, { name: 'Norman Fucking Rockwell' , id:20190830, comment: 'Plz buy Norman Fucking Rockwell on everywhere' , time: '2019年9月16日 18:43' , commentNum:0, like:5, inputShow: false , reply:[] }, ] } }, directives: {clickoutside}, methods: { inputFocus(){ var replyInput = document.getElementById( 'replyInput' ); replyInput.style.padding= "8px 8px" replyInput.style.border = "2px solid blue" replyInput.focus() }, showReplyBtn(){ this .btnShow = true }, hideReplyBtn(){ this .btnShow = false replyInput.style.padding= "10px" replyInput.style.border = "none" }, showReplyInput(i,name,id){ this .comments[ this .index].inputShow = false this .index =i this .comments[i].inputShow = true this .to = name this .toId = id }, _inputShow(i){ return this .comments[i].inputShow }, sendComment(){ if (! this .replyComment){ this .$message({ showClose: true , type: 'warning' , message: '评论不能为空' }) } else { let a ={} let input = document.getElementById( 'replyInput' ) let timeNow = new Date().getTime(); let time= this .dateStr(timeNow); a.name= this .myName a.comment = this .replyComment a.headImg = this .myHeader a.time = time a.commentNum = 0 a.like = 0 this .comments.push(a) this .replyComment = '' input.innerHTML = '' ; } }, sendCommentReply(i,j){ if (! this .replyComment){ this .$message({ showClose: true , type: 'warning' , message: '评论不能为空' }) } else { let a ={} let timeNow = new Date().getTime(); let time= this .dateStr(timeNow); a.from= this .myName a.to = this .to a.fromHeadImg = this .myHeader a.comment = this .replyComment a.time = time a.commentNum = 0 a.like = 0 this .comments[i].reply.push(a) this .replyComment = '' document.getElementsByClassName( "reply-comment-input" )[i].innerHTML = "" } }, onDivInput: function (e) { this .replyComment = e.target.innerHTML; }, dateStr(date){ //获取js 时间戳 var time= new Date().getTime(); //去掉 js 时间戳后三位,与php 时间戳保持一致 time=parseInt((time-date)/1000); //存储转换值 var s; if (time<60*10){ //十分钟内 return '刚刚' ; } else if ((time=60*10)){ //超过十分钟少于1小时 s = Math.floor(time/60); return s+ "分钟前" ; } else if ((time=60*60)){ //超过1小时少于24小时 s = Math.floor(time/60/60); return s+ "小时前" ; } else if ((time=60*60*24)){ //超过1天少于30天内 s = Math.floor(time/60/60/24); return s+ "天前" ; } else { //超过30天ddd var date= new Date(parseInt(date)); return date.getFullYear()+ "/" +(date.getMonth()+1)+ "/" +date.getDate(); } } }, } |
css 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | .my-reply padding 10px background-color #fafbfc .header-img display inline-block vertical-align top .reply-info display inline-block margin-left 5px width 90% @media screen and (max-width:1200px) { width 80% } .reply-input min-height 20px line-height 22px padding 10px 10px color #ccc background-color #fff border-radius 5px &:empty:before content attr(placeholder) &:focus:before content none &:focus padding 8px 8px border 2px solid blue box-shadow none outline none .reply-btn-box height 25px margin 10px 0 .reply-btn position relative float right margin-right 15px .my-comment-reply margin-left 50px .reply-input width flex .author-title:not(:last-child) border-bottom: 1px solid rgba(178,186,194,.3) .author-title padding 10px .header-img display inline-block vertical-align top .author-info display inline-block margin-left 5px width 60% height 40px line-height 20px >span display block cursor pointer overflow hidden white-space nowrap text-overflow ellipsis .author-name color #000 font-size 18px font-weight bold .author-time font-size 14px .icon-btn width 30% padding 0 !important float right @media screen and (max-width : 1200px){ width 20% padding 7px } >span cursor pointer .iconfont margin 0 5px .talk-box margin 0 50px >p margin 0 .reply font-size 16px color #000 .reply-box margin 10px 0 0 50px background-color #efefef |
写在最后
如果代码有什么问题,或者你有什么意见,欢迎大家指出。
到此这篇关于利用Vue+ElementUi实现评论功能的文章就介绍到这了,更多相关Vue ElementUi评论内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!