Render函数:留言列表组件

Posted linbudu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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="width: 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的小组件写下来,写的我真的好佩服尤大...

<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>Document</title>
<scriptsrc="Vue.2.6.10.js"></script>
</head>
<style>
[v-cloak]
display: none;
*
padding: 0;
margin: 0;
.message
width: 450px;
text-align: right;
.messagediv
margin-bottom: 12px;
.messagespan
display: inline-block;
width: 100px;
vertical-align: top;
.messageinput, .messagetextarea
width: 300px;
height: 32px;
padding: 0 6px;
color:#657180;
border: 1px solid #d7dde4;
border-radius: 4px;
cursor: text;
outline: none;
.messageinput:focus, .messagetextarea:focus
border: 1px solid #3399ff;
.messagetextarea
height: 60px;
padding: 4px 6px;
.messagebutton
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-itemspan
display: block;
width: 60px;
float: left;
color:#39f;
.list-msg
display: block;
width: 60px;
text-align: justify;
.list-msga
color: #9ea7b4;
cursor: pointer;
float: right;

.list-msga:hover
color:#39f;
.list-nothing
text-align: center;
color:#9ea7b4;
padding: 20px;


</style>
<body>
<divid="app"v-cloakstyle="width: 500px;margin:0 auto; margin-top: 30px;">
<divclass="message">
<v-inputv-model=‘username‘></v-input>
<v-textareav-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;
returnh(‘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;
returnh(‘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)
returnh(‘div‘,
attrs:
class:‘list‘
,
,list);
else
returnh(‘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>

以上是关于Render函数:留言列表组件的主要内容,如果未能解决你的问题,请参考以下文章

使用render函数渲染组件

Render函数

vue中的render函数h()函数函数式组件

render()--组件--纯函数

在vue中使用render函数

使用 render() 函数渲染的组件内的动态组件