Vue.js入门 0xF Render函数(5)实战:留言列表

Vue.js入门 0xF Render函数(5)实战:留言列表_第1张图片

Vue.js入门 0xF Render函数(5)实战:留言列表_第2张图片

 index.html



    
        
        留言列表
        
    
    
        

index.js

var app = new Vue({
    /**
     * 发布一条留言,需要的数据有昵称和留言内容,发布操作应该在
     * 根实例app内完成,留言列表的数据也是从app获取。
     */
    el:'#app',
    data:{
        username:'',//用户名
        message:'',//留言内容
        list:[]//存储所有的留言内容
    },
    methods:{
        //给list添加一项留言数据,添加成功后,把textarea文本框置空
        handleSend:function(){
            if(this.username===''){
                window.alert('请输入昵称');
                return;
            }
            if(this.message===''){
                window.alert('请输入留言内容');
                return;
            }
            this.list.push({
                name:this.username,
                message:this.message
            });
            this.message='';
        },
        //回复留言
        handleReply:function(index){
            //提取昵称并设置到v-textarea
            var name = this.list[index].name;
            this.message = '回复@'+name+':';
            this.$refs.message.focus();
        }
    }
});

input.js

/**
 * 使用v-model:动态绑定value,并监听input事件,
 * 把输入的内容通过$emit('input')派发给父组件。
 */
Vue.component('vInput',{
    props:{
        value:{
            type:[String,Number],
            default:''
        }
    },
    render:function(h){
        var _this = this;
        return h('div',[
            h('span','昵称:'),
            h('input',{
                attrs:{
                    type:'text'
                },
                domProps:{
                    value:this.value
                },
                on:{
                    //监听数据
                    input:function(event){
                        _this.value = event.target.value;
                        //更新数据
                        _this.$emit('input',event.target.value);
                    }
                }
            })
        ]);
    }
});
Vue.component('vTextarea',{
    props:{
        value:{
            type:String,
            default:''
        }
    },
    render:function(h){
        var _this = this;
        return h('div',[
            h('span','留言内容:'),
            h('textarea',{
                attrs:{
                    placeholder:'请输入留言内容'
                },
                domProps:{
                    value:this.value
                },
                ref:'message',
                on:{
                    input:function(event){
                        _this.value = event.target.value;
                        _this.$emit('input',event.target.value);
                    }
                }
            })
        ]);
    },
    methods:{
        focus:function(){
            this.$refs.message.focus();
        }
    }
});

list.js

Vue.component('list',{
    props:{
        list:{
            type:Array,
            default:function(){
                return [];
            }
        }
    },
    render:function(h){
        var _this = this;
        var list = [];
        this.list.forEach(function(msg,index){
            var node = h('div',{
                attrs:{
                    class:'list-item'
                }
            },[
                h('span',msg.name+':'),
                h('div',{
                    attrs:{
                        class:'list-msg'
                    }
                },[
                    h('p',msg.message),
                    h('a',{
                        attrs:{
                            class:'list-reply'
                        },
                        on:{
                            click:function(){
                                _this.handleReply(index);
                            }
                        }
                    },'回复')
                ])
            ])
            list.push(node);
        });
        if(this.list.length){
            return h('div',{
                attrs:{
                    class:'list'
                }
            },list);
        }else{
            return h('div',{
                attrs:{
                    class:'list-nothing'
                }
            },'留言列表为空');
        }
    },
    methods:{
        //向父组件派发事件reply
        handleReply:function(index){
            this.$emit('reply',index);
        }
    }
});

style.css

[v-cloak]{
    display: none;
}
*{
    padding: 0;
    margin: 0;
}
.message{
    width: 450px;
    text-align: right;
}
.message div{
    margin-bottom: 12px;
}
.message span{
    display: inline-block;
    width: 100px;
    vertical-align: top;
}
.message input,.message textarea{
    width: 300px;
    height: 32px;
    padding: 0 6px;
    color: #657180;
    border: 1px solid #d7dde4;
    border-radius: 4px;
    cursor: text;
    outline: none;
}
.message input:focus,.message textarea:focus{
    border: 1px solid #3399ff;
}
.message textarea{
    height: 60px;
    padding: 4px 6px;
}
.message button{
    display: inline-block;
    padding: 6px 15px;
    border: 1px solid #39f;
    border-radius: 4px;
    color: #fff;
    background-color: #39f;
    cursor: pointer;
    outline: none;
}
.list{
    margin-top: 50px;
}
.list-item{
    padding: 10px;
    border-bottom: 1px solid #e3e8ee;
    overflow: hidden;
}
.list-item span{
    display: block;
    width:60px;
    float: left;
    color: #39f;
}
.list-msg{
    display: block;
    margin-left: 60px;
    text-align: justify;
}
.list-msg a{
    color: #9ea7b4;
    cursor: pointer;;
    float: right;
}
.list-msg a:hover{
    color: #39f;
}
.list-nothing{
    text-align: center;
    color:#9ea7b4;
    padding: 20px;
}

 

你可能感兴趣的:(前端基础,JavaScript,Vue)