9:Render函数
Posted linbudu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9: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>
<body>
<!-- 写在前面:虚拟dom,是一个轻量级的js对象,在状态发生变化时,进行Diff运算,对比,生成补丁对象,并更新DOM节点,
与传统dom操作相比,其是基于js计算的,所以开销会少上不少。 -->
<div id="app1">
<ele></ele>
</div>
<div id="app2">
<ele2></ele2>
</div>
<div id="app3">
<ele3></ele3>
</div>
<div id="app4">
<ele4></ele4>
</div>
<div id="app5">
<ele5>
<div>
<child5></child5>
</div>
</ele5>
</div>
</body>
<script>
//Vnode对象通过一些特定的选项,描述了真实的dom结构
var vNode =
tag:‘div‘,
attributes:
id:‘container‘
,
children:
//...
;
// 一个render函数的例子
Vue.component(‘ele‘,
render(createElement)
return createElement(
‘div‘,
//可选的数据对象,包括style、props、dom属性、on、nativeOn(仅对于指令,用于监听原生而非$emit事件)、自定义指令、作用域slot、具名slot等
class:
‘show‘:this.show//动态绑定class
,
attrs:
id:‘element‘//html特型
,
on:
click:this.handleClick//给div绑定click事件
,
‘文本内容‘
)
,
data()
return
show:true
,
methods:
handleClick:function()
console.log(‘clicked!‘);
,
);
var app1 = new Vue(
el:"#app1"
);
//在所有组件树中,如果vNode是组件或含有组件的slot,那么vnode必须唯一,以下给出两个错误示例
var childCom =
render:function(createElement)
return createElement(‘p‘,‘text‘)//省略数据对象形式,渲染结果为<p>text</p>
;
Vue.component(‘ele2‘,
render:function(createElement)
//创建一个子节点(使用子组件childCom)
var childNode = createElement(childCom);
return createElement(‘div‘,[
childNode,
childNode
])//子节点的传入形式可以是字符串或者数组
);
var app2 = new Vue(
el:"#app2"
);
//错误示例2,重复使用含有组件的slot
Vue.component(‘child‘,
render:function(createElement)
return createElement(‘p‘,‘text‘);
);
Vue.component(‘ele3‘,
render(createElement)
createElement(‘div‘,[
this.$slots.default,
this.$slots.default
])
,
);
var app3 = new Vue(
el:"#app3"
);
//这两个实例中都在组件里使用了重复的vnode,
// 第一种情况vnode是局部注册的组件,第二种
//是含有组件的slot(复习:即<div></div>部分,使用$slots.default访问得到,其内部又含有组件)
//正确的重复渲染多个组件的方法:
var child4 =
render:function(createElement)
return createElement(‘p‘,"text");
;
Vue.component(‘ele4‘,
render:function(createElement)
return createElement(‘div‘,
Array.apply(null,//将global对象作为thisObj
length:5
).map(function()
return createElement(child4);
))
);
var app4 = new Vue(
el:"#app4"
);
//对于带有组件的slot,复用需要将slot的每个子节点都克隆一份
Vue.component(‘child5‘,
render:function(createElement)
return createElement(‘p‘,‘text‘);
);
Vue.component(‘ele5‘,
render:function(createElement)
//深度克隆slot节点
function cloneVNode(vnode)
const clonedChildren = vnode.children &&
vnode.children.map(function(vnode)
return cloneVNode(vnode);
);//返回的是vnode数组对象
console.log(clonedChildren);
const cloned = createElement(
vnode.tag,//‘div’
vnode.data,//object
clonedChildren//子节点(数组/字符串形式)
);
cloned.text = vnode.text;//克隆节点的关键属性值等于传入的slot子节点的关键属性
cloned.isComment = vnode.isComment;
cloned.componentOptions = vnode.componentOptions;
cloned.elm = vnode.elm;
cloned.context = vnode.context;
cloned.ns = vnode.ns;
cloned.isStatic = vnode.isStatic;
cloned.key = vnode.key;
return cloned;
const vNodes = this.$slots.default;
console.log(vNodes);//<div>...</div>
const clonedVNodes = vNodes.map(function(vnode)
console.log(vnode);//在这里slot只有一个子节点,因此遍历也只会遍历这一个
return cloneVNode(vnode);
);
console.log(clonedVNodes);
//获取slot插槽内的内容(子节点),使用map方法依次执行cloneVnode
//函数,在该函数中进行关键属性的复制
return createElement(‘div‘,[
vNodes,
clonedVNodes,
clonedVNodes//可以重复
]);
);
var app5 = new Vue(
el:"#app5"
);
</script>
</html>
以上是关于9:Render函数的主要内容,如果未能解决你的问题,请参考以下文章