虚拟DOM技术(Virtual DOM,VDOM)

VDOM的第一个目的:完成在Vue下实现DOM操作的功能。
VDOM的第二个目的:实现比原生的DOM操作还要快的页面渲染机制。
VDOM的本质:利用js对象模拟DOM节点。
一、利用render函数代替组件中的template:
1、render函数的功能:在创建组件是实现DOM结构的生产,和template完全一致。
2、格式:
Vue.component(‘my-com’,{
render:function(createElement){
return createElement(‘div’);
}
//相当于 template:<div></div>
})
使用组件:
3、简化格式:
Vue.component(‘my-com’,{
render:h=>h(‘div’)
})
4、创建一个带有文本内容的VDOM节点:

我天上课之前画了一个满之慧

render:h=>h(‘div’,‘我天上课之前画了一个满之慧’)
5、创建一个VDOM节点:
带有名为box的类名,内联样式规定了宽度、高度、背景颜色,具备id属性和title属性。
能够为这个VDOM节点绑定鼠标经过和鼠标离开的事件。

解决方案:使用h()函数的第二个参数,参数类型为{}。 格式:h(‘tagName’,{ class:{ //为VDOM节点设置类名 }, style:{ //为VDOM节点设置内联样式}, attrs:{ //为VDOM节点设置HTML属性}, on:{ //为VDOM节点绑定事件}, domProps:{ //为VDOM节点设置JavaScript中的节点属性} }) 例如:render:h=>h('div',{ class:{box:true}, style:{width:'200px',height:'100px',backgroundColor:'#3385ff'}, attrs:{id:'box',title:'鼠标经过显示文本'}, on:{ mouseover:()=>event.target.style.backgroundColor='#ff5857', mouseout:()=>event.target.style.backgroundColor='#3385ff' }, domProps:{ innerText:'我是通过h函数生成的VDOM节点', contentEditable:true } }) 6、创建一个带有子节点的VDOM节点: 格式:h(‘div’,[h(),h()]) 例如: render:h=>h('div',{ class:{box:true} },[ h('h1','我是一级标题'), h('div',[ h('p','我是一个段落'), h('a',{ attrs:{href:'#'} },'百度百科') ]) ]) 二、根据现有组件创建VDOM节点: 1、例1:根据现有组件my-book创建VDOM节点。 Vue.component(‘my-book’,{ template:`
书名
` }) Vue.component(‘my-com’,{ render:h=>h(‘my-book’) }) 2、例2:根据带有插槽的现有组件创建VDOM节点。 Vue.component('my-book',{ template:`
` }) Vue.component('my-com',{ // render:h=>h(‘my-book’,‘书名作者’) render:h=>h('my-book',[h('div','我和我的VUE')]) }) 3、例3:根据带有参数的现有组件创建VDOM节点。 Vue.component('my-book',{ template:`

书名:{{bookName}}

作者:{{author}}

出版社:{{publish}}

`, props:['bookName','author','publish'] })

Vue.component(‘my-com’,{
render:h=>h(‘my-book’,{
props:{
bookName:‘满之慧与伏地魔’,
author:‘裴嘉靖’,
publish:‘金梅出版社’
}
})
})
4、例4:让现有组件作为VDOM节点的子节点。
render:h=>h(‘div’,[
h(‘h1’,‘2020年畅销书’),
h(‘my-book’,{
props:{
bookName:‘满之慧与伏地魔’,
author:‘裴嘉靖’,
publish:‘金梅出版社’
}
})
])
三、创建具备插槽的VDOM节点:
注意:具备插槽的VDOM节点不能使用箭头函数。
1、例1:创建具备一个匿名插槽的VDOM节点。
DOM结构格式:template:<div><slot></slot></div>
render(h){
return h(‘div’,this.KaTeX parse error: Expected 'EOF', got '}' at position 17: …lots.default); }̲ 使用:<my-com>我被放…slots.default)
])
}
(2)创建一个超级链接的VDOM节点。
template:<div><a :href=“url”><slot></slot></a></div>
render(h){
return h(‘div’,[
h(‘a’,{
attrs:{href:this.url}
},this.$slots.default)
])
},
props:[‘url’]
使用:百度百科
2、例2:创建具备多个具名插槽的VDOM节点。
template:`

` render(h){ return h('div',[ h('h1',this.$slots.abc), h('h2',this.$slots.xyz) ]) } 使用: 哈利波特与魔法石 JK罗琳 3、例3:创建具备一个默认作用域插槽的VDOM节点。 render(h){ return h('div',this.$scopedSlots.default({ a:100, b:200, c:50 })) } 使用: {{sc.a}}+{{sc.b}}+{{sc.c}}={{sc.a+sc.b+sc.c}} 4、例4:创建具备多个具名的作用域插槽的VDOM节点。 render(h){ return h('div',[ h('h1',this.$scopedSlots.abc({a:100,b:200})), h('h2',this.$scopedSlots.xyz({x:'A',y:'B'})) ]) } 使用: {{sc.a}}+{{sc.b}}={{sc.a+sc.b}} {{sc.x}}+{{sc.y}} 四、在render函数中使用Vue指令: 1、利用render函数实现的组件模板不能使用vue指令。 2、例:当list数组中的元素>3个时,遍历出数组的所有内容并显示出来,否则提示内容不 足。 (1)使用传统的template来创建组件。 Vue.component('my-com',{ template:`
  • {{item}}

数据内容不足

`, props:['list'] }) (2)使用render函数来创建VDOM节点。 Vue.component('my-com',{ render(h){ let vnode; if(this.list.length>3){ //创建循环遍历的VDOM节点 vnode=h('ul',this.list.map(item=>h('li',item))); }else{ //创建提示数据不足的VDOM节点 vnode=h('p','数据内容不足'); } return h('div',{ class:{com:true} },[vnode]); }, props:['list'] }) 五、在element-ui中使用render函数: 1、在element-ui的表格组件中,具备一个属性 render-header,该属性的功 能是返回列表头的内容。 (1)可以返回一个字符串作为表头的新标签内容。 (2)可以返回一个VDOM节点作为表头的内容。 2、如何在VDOM中为表单元素绑定数据(VDOM不能使用v-model指令): 在表单元素的input事件中,让表单元素的value属性的取值赋给一个侦听属性。 3、案例:

认识一个开源的VDOM项目:Snabbdom
1、打包工具:parcel
安装 npm install -g parcel-bundler
执行项目:parcel index.html
打包:parcel build index.html
2、下载snabbdom
npm install snabbdom@0.7.4
snabbdom是使用TypeScript来进行书写的。
3、引入snabbdom:
ES6:import from
CommonJS:require()
例:import {h,init} from ‘snabbdom’
4、使用到的函数:
init():参数是数组,返回值为patch()函数。
patch():将生成的VDOM节点放入到挂载点的DOM结构内部。
h():生成VDOM节点。
例1:利用Snabbdom生成一个div节点,并放在HTML的结构中,实现Hell,Snabbdomo
功能。
import {h,init} from ‘snabbdom’;
let patch=init([]);
let vnode=h(‘div’,‘Hello,Snabbdom!’);
let app=document.querySelector(‘#app’);
patch(app,vnode);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值