Render函数(2):使用原生js替代自定义指令、修饰符、slot
<!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>
<div id="app1">
<ele1 :show="show"></ele1>
<button @click="show = !show">切换show的值</button>
</div>
<div id="app2">
<ele2 :list='list'></ele2>
</div>
<div id="app3">
<ele3 :list='list'></ele3>
<button @click='handleClick'>显示列表</button>
</div>
<div id="app4">
<ele4></ele4>
</div>
<div id="app5">
<ele5></ele5>
</div>
<div id="app6">
<ele6>
<p>有我在,备用内容不会出现</p>
</ele6>
</div>
</body>
<script>
//在render函数中,不再需要也无法使用Vue的内置指令,如v-if、v-show,但均可通过原生js实现
//数据变化--render函数生成新的虚拟dom--更新
Vue.component('ele1',{
render(createElement) {
if(this.show){
return createElement('p','show的值为true');
}else{
return createElement('p','show的值为false');
}
},
props:{
show:{
type:Boolean,
default:false
}
}
});
var app1 = new Vue({
el:"#app1",
data:{
show:false
}
});
//使用for循环来实现v-for
Vue.component('ele2',{
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 app2 = new Vue({
el:"#app2",
data:{
list:[
'book1',
'book2',
'book3'
]
}
});
//使用if、else、数组map方法配合来渲染一个列表
Vue.component('ele3',{
render:function(createElement){
if(this.list.length){
return createElement('ul',this.list.map(function(item){
return createElement('li',item);
}));
}else{
return createElement('p','列表当前为空')
}
},
props:{
list:{
type:Array,
default:function(){
return []
}
}
}
});
var app3 = new Vue({
el:"#app3",
data:{
list:[]
},
methods: {
handleClick:function(){
//点击后才会将项目添加到列表
this.list = [
'book11',
'book22',
'book33'
]
}
},
});
//实现v-model逻辑
Vue.component('ele4',{
render:function(createElement){
var _this = this;
return createElement('div',[
createElement('input',{
domProps:{
value:this.value
},
on:{
input:function(event){
_this.value = event.target.value;
}
}
}),
createElement('p','value: '+ this.value)
])
},
data() {
return {
value:''
}
},
});
var app4 = new Vue({
el:'#app4'
});
//所有的事件修饰符与按键修饰符同样需要自己实现
//.stop event.stopPropogation()
//.prevent event.preventDefault()
//.self if(e.target !== e.currentTarget)
//.enter .13 if(event.keyCode !== 13)
//.ctrl/.alt if(!e.ctrlKey/altKet)return
//.capture(!) .once(~)
//capture先执行父级事件再执行子级事件 self只执行子级事件
//模拟聊天发生内容场景
Vue.component('ele5',{
render:function(createElement){
var _this = this;
//渲染聊天内容列表
if(this.list.length){
var listNode = createElement('ul',this.list.map(function(item){
return createElement('li',item)
}));
}else{
var listNode = createElement('p','暂无内容');
}
return createElement('div',[
listNode,
createElement('input',{
attrs:{
placeholder:'回车发送'
},
style:{
width:'200px'
},
on:{
keyup:function(e){
if(e.keyCode != 13) return;
_this.list.push(e.target.value);
e.target.value = '';//发送成功清空输入框
}
}
})
])
},
data() {
return {
value:'',
list:[]
}
},
});
var app5 = new Vue({
el:"#app5"
});
Vue.component('ele6',{
render:function(createElement){
console.log(this.$slots.default);
if(this.$slots.default === undefined){
return createElement('div','备用内容')
} else {
return createElement('div',this.$slots.default);
}
}
});
var app6 = new Vue({
el:'#app6'
});
</script>
</html>