一、为什么要使用虚拟DOM
- 首先说说为什么要使用Virturl DOM,因为操作真实DOM的耗费的性能代价太高,所以Vue内部使用js实现了一套dom结构,在每次操作在和真实dom之前,使用实现好的diff算法,对虚拟dom进行比较,递归找出有变化的dom节点,然后对其进行更新操作。
- 为了实现虚拟DOM,我们需要把每一种节点类型抽象成对象,每一种节点类型有自己的属性,也就是prop,每次进行diff的时候,会先比较该节点类型,假如节点类型不一样,那么Vue会直接删除该节点,然后直接创建新的节点插入到其中,假如节点类型一样,那么会比较prop是否有更新,假如有prop不一样,那么Vue会判定该节点有更新,那么重渲染该节点,然后在对其子节点进行比较,一层一层往下,直到没有子节点。
二、使用虚拟DOM
1、代码示例
<template>
<div class="container">
<y-div @click="outerFny" level="1"></y-div>
</div>
</template>
<script>
export default {
components: {
'y-div': {
data() {
return {
value: '123'
}
},
props: ['level'],
render: function (createElement) {
return createElement(
'div',
{
'class': {
foo: true,
bar: false
},
style:{
width:'100px',
height:'100px',
}
},
[
createElement('p',{
on: {
click: this.handler
},
'class': {
foo: true,
bar: false
},
style: {
fontSize: '14px',
},
},'nnnnnnnnn'),
createElement('p','wwwwwww')
]
)
},
methods: {
handler() {
console.log('value', this.value);//123
this.$emit('click', {a: '1', b: '2'})
}
}
},
},
methods: {
outerFny(e) {
console.log(e);// {a: '1', b: '2'}
}
}
}
</script>
2、render函数的一个参数
- 第一个参数必选, string|Object|Function
Vue.component('child', {
//String--html标签
//Object---一个含有数据选项的对象
//FUnction---方法返回含有数据选项的对象
render: function (createElement) {
alert(typeof createElement)
// return createElement('h1')
// return createElement({
// template:'<div>锄禾日当午</div>'
// })
var domFun = function () {
return {
template: '<div>锄禾日当午</div>'
}
}
return createElement(domFun());
}
});
3、render函数的第二个参数
- 第二个参数可选,第二个参数是数据对象—-只能是Object
Vue.component('child', {
render: function (createElement) {
return createElement({
template: '<div>我是龙的传人</div>'
}, {
'class': {
foo: true,
baz: false
},
style: {
color: 'red',
fontSize: '16px'
},
//正常的html特性
attrs: {
id: 'foo',
src: 'http://baidu.com'
},
//用来写原生的Dom属性
domProps: {
innerHTML: '<span style="color:blue;font-size: 1
8px">我是蓝色</span>'
}
})
}
});
4、render函数的第三个参数
- 第三个参数也是可选===String | Array—作为我们构建函数的子节点来使用的
Vue.component('child',{
// ----第三个参数是可选的,可以是 String | Array---代表子节点
render: function (createElement) {
return createElement('div',[
createElement('h1','我是h1标题'),
createElement('h6','我是h6标题')
])
}
});
5、this.$slots在render函数中的应用
<my-component>
<div slot="header">1</div>
<div slot="default">2</div>
<div slot="footer">3</div>
</my-component>
Vue.component('my-component',{
render:function (createElement) {
var header = this.$slots.header; //--这返回的内容就是含有=VNODE的数组
var main = this.$slots.default;
var footer = this.$slots.footer;
return createElement('div',[
createElement('header',header),
createElement('main',main),
createElement('footer',footer)
]);
}
})