vue组件实现发表评论功能(localStorage)

首先画出简单的界面如下:

说说我的思路:由于是为了去练习组件之间传值,所以将页面上的写评论部分写在了子组件中,然后在然后然后子组件点击发表将数据传递给父组件的data,再由父组件来渲染评论社区的页面。

1.先主实例的data中写一个固定的评论列表,然后在页面上利用v-for来渲染实现页面效果。

2.在模板中定义一个方法publishctx,用来发表数据,但是如何拿到评论人和评论内容呢?

    2.1运用v-model来动态绑定数据。

    2.2在方法中定义一个对象,用来存放拿到到数据。

    2.3利用localstorage来实现本地存储和数据的获取。将从local'storage中获取到的数据转化成对象格式放入list中,覆盖原有的list.然后重新把数据保存在本地。这里只是实现了本地存储,而页面上如何拿到发表的数据,且看下一步。

3.现在需要在实例对象中定义一个方法localComment(),从本地存储localstorage中来获得数据列表,并将拿到的数据列表覆盖原有的列表。然后在created中调用这个方法实现页面渲染的效果。但是呢?这一步当你点击发表后,并不会立即在页面上出现你发表的内容,你需要手动更新数据,这显然是不合理的。

所以需要在子组件的publishctx方法中调用localComment方法。这里就涉及了子组件调用父组件的方法。

在父组件中绑定方法:localComment,在子组件中利用this.$emit()来调用。

下面是详细代码区域,有问题欢迎提问。前端小白学习路~~~

<div id="app" style="padding: 20px">
    <comts @func="localComment"></comts>
    <h3>评论社区:</h3>
    <ul class="list-group">
        <li class="list-group-item" v-for="item in list">
            <span class="badge">{{item.id|dataformat('')}}:{{item.name}}</span>
            {{item.content}}
        </li>
    </ul>
</div>
<template id="tmp1">
    <div>
        <form role="form">
            <div class="form-group">
                <label for="name">评论人:</label>
                <br>
                <div class="col-lg-8">
                    <input type="text" class="form-control" placeholder="请输入..." v-model="name">
                </div>

            </div>
            <br>
            <div class="form-group">
                <label for="content">评论内容:</label>
                <textarea class="form-control" rows="3" v-model="content"></textarea>
            </div>
        </form>
        <input type="button" value="发表" class="btn btn-primary" @click="publishctx">
    </div>
</template>
<script>
//这个全局过滤器用来过滤时间,将时间转换成我们经常看的形式:yyyy-mm-dd
    Vue.filter('dataformat',function(datastr,pattern){
        var dt=new Date(datastr);
        var y=dt.getFullYear();
        var m=(dt.getMonth()+1).toString().padStart(2,'0');
        var d=dt.getDate().toString().padStart(2,'0');
        
        if(pattern.toLocaleLowerCase()=='yyyy-mm-dd'){
            return `${y}-${m}-${d}`;
        }else{
            var hh=dt.getHours();
            var mm=dt.getMinutes();
            var ss=dt.getSeconds();
            return`${y}-${m}-${d} ${hh}:${mm}:${ss}`;
        }
    })
//这一部分是子组件,
    var commentBox={
        data:function(){
            return{
                name:'',
                content:'',
            }
        },
        template:'#tmp1',
        methods:{
            publishctx(){
        var comment={id:Date.now(),name:this.name,content:this.content};
        //从Localstorage获取到数据
        var list=JSON.parse(localStorage.getItem('ctx')||'[]');
        //把拿到的数据放在放入list中
        list.unshift(comment);
        //重新把评论数据保存在本地
        localStorage.setItem('ctx',JSON.stringify(list));
        //清空数据
        this.name=this.content='';
        this.$emit('func');
    }
    }
    };
    var vm=new Vue({
        el:'#app',
        data:{
            list:[
                {id:'Date.now()',name:'李白',content:'抽刀断水水更流'},
                {id:'Date.now()',name:'孟浩然',content:'千里江陵一日还'},
            ]
        },
        created:function(){
            return this.localComment();
        },
        methods:{
            localComment(){
               //从本地的localstorage中加载评论列表
                var list=JSON.parse(localStorage.getItem('ctx')||'[]');
                this.list=list;
             }
        },
        components:{
           'comts':commentBox
        },
    })
</script>
发布了79 篇原创文章 · 获赞 36 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/yezi__6/article/details/90047920
今日推荐