• Render函数:留言列表组件


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="Vue.2.6.10.js"></script>
    </head>
    <style>
        [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 #e3e833;
            overflow: hidden;
        }
        .list-item span{
            display: block;
            width: 60px;
            float: left;
            color:#39f;
        }
        .list-msg{
            display: block;
            width: 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;
    
        }
    
    </style>
    <body>
        <div id="app" v-cloak style=" 500px;margin:0 auto; margin-top: 30px;">
            <div class="message">
                <v-input v-model='username'></v-input>
                <v-textarea v-model='message' ref="message"></v-textarea>
                <button @click='handleSend'>发布</button>
            </div>
            <list :list='list' @reply='handleReply'></list>
        </div>
    </body>
    <script>
        Vue.component('vInput',{
            props:{
                value:{
                    type:[String,Number],
                    default:''
                }
            },
            render(h) {
                var _this = this;
                return h('div',[
                    h('span','昵称:'),
                    h('input',{
                        attrs:{
                            type:'text'
                        },
                        domProps:{
                            value:this.value  
                        },
                        on:{
                            //v-model在render中需要自己实现嗷
                            input:function(event){
                                _this.value = event.target.value;
                                _this.$emit('input',event.target.value)
                            }
                        }
                    })
                ])
            },
        });
    
        Vue.component('vTextarea',{
            props:{
                value:{
                    type:String,
                    default:''
                }
            },
            render(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()
                }
            }
        })
    
        Vue.component('list',{
            props:{
                list:{
                    type:Array,
                    default:function(){
                        return [];
                    }
                }
            },
            render(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:{
                handleReply:function(index){
                    this.$emit('reply',index);
                }
            }
        });
    
        //发布留言需要的数据主要有:昵称、留言内容,发布操作在根实例内完成,留言列表数据同样获取自app
        var app = new Vue({
            el:"#app",
            data:{
                username:'',
                message:'',
                list:[]
            },
            methods: {
                handleSend:function(){
                    if(this.username === ''){
                        window.alert('要输入昵称噢');
                        return
                    }
                    if(this.message === ''){
                        window.alert('说点什么吧~');
                        return
                    }
                    this.list.push({
                        //List是一个对象数组?
                        name:this.username,
                        message:this.message
                    });
                    console.log(this.list);
                    this.message = '';//置空输入栏
                },
                handleReply:function(index){
                    var name = this.list[index].name;
                    this.message = '回复@' + name + ":";
                    this.$refs.message.focus();
                }
            },
        });
    
        //分析一哈:
        //v-input组件:生成<span>昵称</span>与输入栏,
        // 并设置输入栏的值为这个组件得到的值:在render函数中用on选项实现v-model
        //(需要domPropsyuon配合来实现双向绑定)当触发input事件,将v-input组件的value更新为
        //同时向根实例发送一个input事件
    
        //v-textarea组件:生成<span>留言内容<span>与文本输入域,在这里同样手动实现v-model
        //该组件中多包含了一个focus方法,this.$refs.message.focus()使得这个实例中render函数生成的textarea获得焦点
    
        //点击回复按钮,调用handleSend(),将昵称与留言内容传入list,置空输入栏,
    
        //▲list组件
        //接收到list后,使用list来渲染留言列表,同时在‘回复’按钮上传入昵称对应的index,当点击时调用handleReply方法
        //它的reply方法是为了调用根实例的同名方法
        //
    </script>
    </html>
    View Code

    预览效果:

    这几个Vue的小组件写下来,写的我真的好佩服尤大...

  • 相关阅读:
    SQL server 事务介绍,创建与使用
    DOM操作系列-01
    JS键盘事件
    Js获取当前日期时间及其它操作
    js中!!的作用
    js == 与 === 的区别[转]
    学习总结--Dom
    css历史
    javascript中 visibility和display的区别
    “==”和Equals区别
  • 原文地址:https://www.cnblogs.com/linbudu/p/11110264.html
Copyright © 2020-2023  润新知