最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用Vue+ElementUi實現(xiàn)評論功能

 更新時間:2024年04月03日 10:42:33   作者:zLanaDelRey  
這篇文章主要介紹了如何利用Vue+ElementUi實現(xiàn)評論功能,結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言

這兩天在用vue重構(gòu)之前寫的一個社區(qū)博客項目,之前評論的樣式和效果都差強人意,所以仿照掘金重寫了一個評論功能(但不是完全照搬模仿)

在寫完這個功能后,由心覺得Vue真的非常好用。

話不多說,先上效果圖

評論效果圖

效果動圖

效果動圖

代碼

html代碼:

<template>
    <div>
        <div v-clickoutside="hideReplyBtn" @click="inputFocus" class="my-reply">
            <el-avatar class="header-img" :size="40" :src="myHeader"></el-avatar>
            <div class="reply-info" >
                <div 
                tabindex="0" 
                contenteditable="true" 
                id="replyInput" 
                spellcheck="false" 
                placeholder="輸入評論..." 
                class="reply-input" 
                @focus="showReplyBtn"  
                @input="onDivInput($event)"
                >
                </div>
            </div>
            <div class="reply-btn-box" v-show="btnShow">
                <el-button class="reply-btn" size="medium" @click="sendComment" type="primary">發(fā)表評論</el-button>
            </div>
        </div>
        <div v-for="(item,i) in comments" :key="i" class="author-title reply-father">
            <el-avatar class="header-img" :size="40" :src="item.headImg"></el-avatar>
            <div class="author-info">
                <span class="author-name">{{item.name}}</span>
                <span class="author-time">{{item.time}}</span>
            </div>
            <div class="icon-btn">
                <span @click="showReplyInput(i,item.name,item.id)"><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 v-for="(reply,j) in item.reply" :key="j" class="author-title">
                    <el-avatar class="header-img" :size="40" :src="reply.fromHeadImg"></el-avatar>
                    <div class="author-info">
                        <span class="author-name">{{reply.from}}</span>
                        <span class="author-time">{{reply.time}}</span>
                    </div>
                    <div class="icon-btn">
                        <span @click="showReplyInput(i,reply.from,reply.id)"><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  v-show="_inputShow(i)" class="my-reply my-comment-reply">
                <el-avatar class="header-img" :size="40" :src="myHeader"></el-avatar>
                <div class="reply-info" >
                    <div tabindex="0" contenteditable="true" spellcheck="false" placeholder="輸入評論..."   @input="onDivInput($event)"  class="reply-input reply-comment-input"></div>
                </div>
                <div class=" reply-btn-box">
                    <el-button class="reply-btn" size="medium" @click="sendCommentReply(i,j)" type="primary">發(fā)表評論</el-button>
            </div>
        </div>
        </div>
    </div>
</template>

JS代碼如下

我把模擬的數(shù)據(jù)寫在了data里面,顯得js有點長。如果要更改數(shù)據(jù)的格式的話,記得也要改Html不然會出錯。

<script>
const clickoutside = {
    // 初始化指令
    bind(el, binding, vnode) {
    function documentHandler(e) {
    // 這里判斷點擊的元素是否是本身,是本身,則返回
        if (el.contains(e.target)) {
            return false;
        }
    // 判斷指令中是否綁定了函數(shù)
        if (binding.expression) {
            // 如果綁定了函數(shù) 則調(diào)用那個函數(shù),此處binding.value就是handleClose方法
            binding.value(e);
        }
    }
    // 給當前元素綁定個私有變量,方便在unbind中可以解除事件監(jiān)聽
    el.vueClickOutside = documentHandler;
    document.addEventListener('click', documentHandler);
    },
    update() {},
    unbind(el, binding) {
    // 解除事件監(jiān)聽
    document.removeEventListener('click', el.vueClickOutside);
    delete el.vueClickOutside;
  },
};
export default {
    name:'ArticleComment',
    data(){
        return{
            btnShow: false,
            index:'0',
            replyComment:'',
            myName:'Lana Del Rey',
            myHeader:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg',
            myId:19870621,
            to:'',
            toId:-1,
            comments:[
                {
                    name:'Lana Del Rey',
                    id:19870621,
                    headImg:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg',
                    comment:'我發(fā)布一張新專輯Norman Fucking Rockwell,大家快來聽啊',
                    time:'2019年9月16日 18:43',
                    commentNum:2,
                    like:15,
                    inputShow:false,
                    reply:[
                        {
                            from:'Taylor Swift',
                            fromId:19891221,
                            fromHeadImg:'https://ae01.alicdn.com/kf/H94c78935ffa64e7e977544d19ecebf06L.jpg',
                            to:'Lana Del Rey',
                            toId:19870621,
                            comment:'我很喜歡你的新專輯!!',
                            time:'2019年9月16日 18:43',
                            commentNum:1,
                            like:15,
                            inputShow:false
                        },
                        {
                            from:'Ariana Grande',
                            fromId:1123,
                            fromHeadImg:'https://ae01.alicdn.com/kf/Hf6c0b4a7428b4edf866a9fbab75568e6U.jpg',
                            to:'Lana Del Rey',
                            toId:19870621,
                            comment:'別忘記宣傳我們的合作單曲啊',
                            time:'2019年9月16日 18:43',
                            commentNum:0,
                            like:5,
                            inputShow:false

                        }
                    ]
                },
                {
                    name:'Taylor Swift',
                    id:19891221,
                    headImg:'https://ae01.alicdn.com/kf/H94c78935ffa64e7e977544d19ecebf06L.jpg',
                    comment:'我發(fā)行了我的新專輯Lover',
                    time:'2019年9月16日 18:43',
                    commentNum:1,
                    like:5,
                    inputShow:false,
                    reply:[
                        {
                            from:'Lana Del Rey',
                            fromId:19870621,
                            fromHeadImg:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg',
                            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,
                    headImg:'https://ae01.alicdn.com/kf/Hdd856ae4c81545d2b51fa0c209f7aa28Z.jpg',
                    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);
            //存儲轉(zhuǎn)換值 
            var s;
            if(time<60*10){//十分鐘內(nèi)
                return '剛剛';
            }else if((time<60*60)&&(time>=60*10)){
                //超過十分鐘少于1小時
                s = Math.floor(time/60);
                return  s+"分鐘前";
            }else if((time<60*60*24)&&(time>=60*60)){ 
                //超過1小時少于24小時
                s = Math.floor(time/60/60);
                return  s+"小時前";
            }else if((time<60*60*24*30)&&(time>=60*60*24)){ 
                //超過1天少于30天內(nèi)
                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();
            }
        }
    },    
}
</script>

css 代碼

<style lang="stylus" scoped>
.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
</style>

寫在最后

如果代碼有什么問題,或者你有什么意見,歡迎大家指出。

到此這篇關(guān)于利用Vue+ElementUi實現(xiàn)評論功能的文章就介紹到這了,更多相關(guān)Vue ElementUi評論內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Vue.js和Element-UI做一個簡單登錄頁面的實例

    使用Vue.js和Element-UI做一個簡單登錄頁面的實例

    下面小編就為大家分享一篇使用Vue.js和Element-UI做一個簡單登錄頁面的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • vant之關(guān)于van-list的使用以及一些坑的解決方案

    vant之關(guān)于van-list的使用以及一些坑的解決方案

    這篇文章主要介紹了vant之關(guān)于van-list的使用以及一些坑的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue 自定義組件 v-model雙向綁定、 父子組件同步通信的多種寫法

    vue 自定義組件 v-model雙向綁定、 父子組件同步通信的多種寫法

    父子組件通信,都是單項的,很多時候需要雙向通信。這篇文章主要介紹了vue 自定義組件 v-model雙向綁定、 父子組件同步通信,需要的朋友可以參考下
    2017-11-11
  • 如何優(yōu)雅的在一臺vps(云主機)上面部署vue+mongodb+express項目

    如何優(yōu)雅的在一臺vps(云主機)上面部署vue+mongodb+express項目

    這篇文章主要介紹了如何優(yōu)雅的在一臺vps(云主機)上面部署vue+mongodb+express項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • vue開發(fā)中后臺系統(tǒng)復雜表單優(yōu)化技巧

    vue開發(fā)中后臺系統(tǒng)復雜表單優(yōu)化技巧

    這篇文章主要為大家介紹了vue開發(fā)中后臺系統(tǒng)復雜表單的優(yōu)化技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Vue組件的使用教程詳解

    Vue組件的使用教程詳解

    組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。這篇文章給大家介紹了vue組件的使用,需要的朋友參考下吧
    2018-01-01
  • Vue開發(fā)之組件通信的常用方案全攻略

    Vue開發(fā)之組件通信的常用方案全攻略

    在 Vue 開發(fā)中,組件通信是構(gòu)建復雜應用的基礎,本文將對比 Vue 2 與 Vue 3,帶你梳理最常用的 5 種通信方案,有需要的小伙伴可以根據(jù)需要進行選擇
    2026-02-02
  • Vue-Element-Admin前端接入SSO的方法步驟

    Vue-Element-Admin前端接入SSO的方法步驟

    本文主要介紹了Vue-Element-Admin前端接入SSO的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • vue學習筆記之Vue中css動畫原理簡單示例

    vue學習筆記之Vue中css動畫原理簡單示例

    這篇文章主要介紹了vue學習筆記之Vue中css動畫原理,結(jié)合簡單實例形式分析了Vue中css樣式變換動畫效果實現(xiàn)原理與相關(guān)操作技巧,需要的朋友可以參考下
    2020-02-02
  • vue中?$forceUpdate的使用解析

    vue中?$forceUpdate的使用解析

    這篇文章主要介紹了vue中?$forceUpdate的使用解析,該方案是比較好的一種方式,比如說我們嘗試直接給某個??object??增加一個屬性,發(fā)現(xiàn)頁面上沒有效果;直接將length變成0來清空數(shù)組,下文詳細資料需要的小伙伴可以參考一下
    2022-04-04

最新評論

孟村| 通化市| 临清市| 宁远县| 襄汾县| 噶尔县| 永兴县| 腾冲县| 五常市| 冷水江市| 通海县| 德化县| 邓州市| 碌曲县| 盖州市| 敦化市| 上饶县| 崇州市| 独山县| 疏勒县| 临夏市| 大姚县| 廊坊市| 丹江口市| 饶平县| 长沙县| 依兰县| 视频| 灵台县| 弥勒县| 井冈山市| 德清县| 临漳县| 碌曲县| 汨罗市| 辽源市| 同德县| 青州市| 鄂托克旗| 甘德县| 福清市|