由浅入深Vue:模拟各大网站留言列表的开发
原创
©著作权归作者所有:来自51CTO博客作者koaxios的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、Render函数解析及用法
场景分析: 在很多文章类型的网站中,都有区分一级标题、二级标题…为了方便分享url,它们都被做成了 锚点 ,点击之后会将内容加载网址后面,以“#”分割。这可以用Render实现——用于防止代码冗杂。这用Vue中的 路由 也完全可以达到,甚至更方便,,, 当然,Render之精妙并不在此。
先看一个小demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render初步</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">这是APP父组件</div>
<script>
var login={ //定义局部子组件
template:'<h1>这是登录组件哦!</h1>'
};
var app=new Vue({
el:'#app',
data:{
},
render:function (createElement) { //render函数——return的结果会覆盖页面中el绑定的容器
return createElement(login);
}
})
</script>
</body>
</html>
Render函数通过createElement参数来创建Virtual Dom,结构精简了很多,Render函数所有神奇的地方都在这个createElement参数里:
createElement()
一般以return的函数出现在“大众”眼中 ,括号里有很多参数,找其中常用的解析一下:
第一个参数必选,可以是一个HTML标签,也可以是一个组件或函数;
{String | Object | Function}
一个HTML标签,组件选项,或一个函数。必须return上述其中一个。
对于第二个参数“ 数据对象 ”,
'div', //在(子组件中)渲染一个div标签(当然,在其中可以有不少标签,如下面demo)
//{Object}
//一个对应属性的数据对象,可选
//您可以在template中使用
{
},
具体选项如下:
{
//和v-bind:class一样的API
'class':{
foo:true,
bar:false
},
//和v-bind:style一样的API
style:{
color:'red',
fontsize:'14px'
},
//正常的HTML特性
attrs:{
id:'foo'
},
//组件props
props:{
myProp:'bar'
},
//DOM属性
domProps:{
innerHTML:'baz'
},
//自定义事件监听器“on”
on:{
click:this.clickHandle //此处写函数名,对应此组件中methods里的函数(这个函数通过$emit()与父组件连接,实现函数)
}
...
}
(上面各属性的属性值都是“比如”,据情况更换)
第三个参数是子节点VNode,可选(在第二个参数中操作的渲染节点,具体见下面demo):
子节点都用createElement包裹。
再来看一个demo:(第10行是子组件,13行在其中渲染一个div,然后在div中操作)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>render实现v-model</title>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<ele></ele>
</div>
<script>
Vue.component('ele',{
render:function (createElement) {
var _this=this;
return createElement('div',[
createElement('input',{
domProps:{
value:this.value
},
on:{
input:function (event) { //event指代“事件”——这里是输入框(的这个框)
_this.value=event.target.value; //这里用_this就是作用域的问题,如果你用this,会发现提示没有this的定义,上面用_this=this就是传入了this的指向,并且防止擅自修改this
}
}
}),
createElement('p','value:'+this.value)
])
},
data:function () {
return {
value:''
}
}
});
var app=new Vue({
el:'#app'
})
</script>
</body>
</html>
还有诸如:自定义指令(directives)、作用域slot(scopedSlots)等,但在此处无用,先不多说了。
基本模板:
Vue.component('子组件标签名',{
render:function(createElement){
return createElement('div',[
...
...
])
}
})
二、函数化组件
Vue.js提供了一个functional的布尔值选项,设置为true可以使组件无状态和无实例,也就是没有data和上下文。这样用render函数返回虚拟节点可以更容易渲染(如文首的小demo),因为函数化组件只是一个函数,渲染开销要小很多。
但据我分析,函数化组件在实际业务中并不常见,其主要用于以下两个场景:
- 程序化地在多个组件中选一个
- 在将children,props,data传递给子组件之前操作它们
留言列表的开发
由于多文件存储,空间太大,故而不占此空间了,上传到了百度网盘中,需要的可随时下载哦~
链接:https://pan.baidu.com/s/10F3RDOnTsMsZjh9s3dVUlQ
提取码:osgu