Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能
约束
所有的组件树中,如果 VNode 是组件或含有组件的 slot,那么 VNode 必须唯一。
重复渲染多个组件(或元素)
<div id="app">
<ele></ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//局部声明组件
var Child = {
render:function(createElement){
return createElement('p','text');
}
};
Vue.component('ele',{
render:function(createElement){
return createElement('div',
Array.apply(null,{
length:5
}).map(function(){
return createElement(Child);
})
);
}
});
var app = new Vue({
el:'#app'
})
</script>
含有组件的 slot复用
<div id="app">
<ele>
<div>
<Child></Child>
</div>
</ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//全局注册组件
Vue.component('Child',{
render:function(createElement){
return createElement('p','text');
}
});
Vue.component('ele',{
render:function(createElement){
//克隆slot节点的方法
function cloneVNode(vnode){
//递归遍历所有子节点,并克隆
const cloneChildren = vnode.children&&
vnode.children.map(function(vnode){
return cloneVNode(vnode);
});
const cloned = createElement(
vnode.tag,
vnode.data,
cloneChildren
);
cloned.text = vnode.text;
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;
const cloneVNodes = vNodes.map(function(vnode){
return cloneVNode(vnode);
});
return createElement('div',[
vNodes,
cloneVNodes
]);
}
});
var app = new Vue({
el:'#app'
})
</script>
使用 JavaScript 代替模板功能
在Render函数中,不再需要Vue内置的指令,比如v-if、v-for,当然,也没办法使用它们。无论要实现什么功能,都可以用原生JavaScript。
v-if、v-else
<div id="app">
<ele :show="show"></ele>
<button @click="show=!show">切换show</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('ele',{
render:function(createElement){
if(this.show){
return createElement('p','show的值为true');
}else{
return createElement('p','show的值为false');
}
},
props:{
show:{
type:Boolean,
default:false
}
}
});
var app = new Vue({
el:'#app',
data:{
show:false
}
})
</script>
v-for
<div id="app">
<ele :list="list"></ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('ele',{
render:function(createElement){
var nodes = [];
for(var i=0;i<this.list.length;i++){
nodes.push(createElement('p',this.list[i]));
}
return createElement('div',nodes);
},
props:{
list:{
type:Array
}
}
});
var app = new Vue({
el:'#app',
data:{
list:[
'《西游记》',
'《三国演义》',
'《红楼梦》',
'《水浒传》'
]
}
})
</script>