Item1Item2虚拟DOM{tag:'ul',attrs:{id:'list"> 【前端面试题】介绍一下虚拟DOM - 开元棋牌api接口_富阳开元名都棋牌_开元棋牌+yg网络 开元棋牌api接口_富阳开元名都棋牌_开元棋牌+yg

【前端面试题】介绍一下虚拟DOM

栏目:房产 来源:中国印刷设备网 时间:2019-10-25
【前端面试题】介绍一下虚拟DOM

vdom 是什么?为何会存在 vdom?

什么是vdom

  • virtual dom,虚拟DOM
  • 用JS模拟DOM结构
  • DOM变化的对比,放在JS层来做
  • 提高重绘性能

DOM

  • Item 1
  • Item 2

虚拟DOM

{
tag: 'ul',
attrs: {
id: 'list'
},
children: [{
tag: 'li',
attrs: { className: 'item' },
children: ['item1']
},
{
tag: 'li',
attrs: { className: 'item' },
children: ['item2']
}
]
}
//className代替class,因为class是js的保留

为什么需要vdom

浏览器最耗费性能就是DOM操作,DOM操作非常昂贵

现在浏览器执行JS速度非常快

这就是vdom存在的原因

diff算法

什么是diff算法

diff算法并不是vdom提出的概念,一直存在

现在应用到vdom中,对比的是两个虚拟dom

去繁就简

  • diff算法非常复杂,实现难度很大,源码量很大
  • 去繁就简,讲明白核心流程,不关心细节
  • 面试官大部分也不清楚细节,但是很关心核心流程
  • 去繁就简之后,依然具有很大的挑战性

vdom为何要使用diff

  • DOM操作是“昂贵”的,因此尽量减少DOM操作
  • 找出本次DOM必须更新的节点来更新,其他的不更新
  • “找出”的过程,就需要diff算法

diff算法实现 diff实现的过程

  • patch(container,vnode)

如何用vnode生成真实的dom节点

 {
tag: 'ul',
attrs: {
id: 'list'
},
children: [
{
tag: 'li',
attrs: {
className: 'item'
},
children:['item 1']
}
]
}

  • Item 1


简单实现算法

function createElement(vnode) {

var tag = vnode.tag;

var attrs = vnode.attrs || {};

var children = vnode.children || [];

if (!tag) {

return null

}

//创建元素

var elem = document.createElement(tag);

//属性

var attrName;

for (attrName in atts) {

if (attrs.hasOwnProperty(attrName)) {

elem.setAttribute(attrName, attrs[attrName])

}

}

//子元素

children.array.forEach(childVnode => {

elem.appendChild(createElement(childVnode))

});

return elem;

}

  • patch(vnode,newVnode)
 {
tag: 'ul',
attrs: { id: 'list' },
children: [{
tag: 'li',
attrs: { className: 'item' },
children: ["Item 1"]
},
{
tag: 'li',
attrs: {
className: 'item',
children: ['Item 2']
}
}
]
}

对比:

{
tag: 'ul',
attrs: { id: 'list' },
children: [{
tag: 'li',
attrs: { className: 'item' },
children: ["Item 1"]
},
{
tag: 'li',
attrs: {
className: 'item',
children: ['Item 222']
}
},
{
tag: 'li',
attrs: {
className: 'item',
children: ['Item 3']
}
}
]
}

【前端面试题】介绍一下虚拟DOM

简单实现

 function updateChildren(vnode, newVnode) {
var children = vnode.children || [];
var newChildren = newVnode.children || [];
//遍历现有的children
children.forEach((child, index) => {
var newChild = newChildren[index];
if (newChild == null) {
return;
}
if (child.tag === newChild.tag) {
updateChildren(child, newChild)
} else {
replaceNode(child, newChild)
}
});
}
  • 节点新增和删除
  • 节点重新排序
  • 节点属性、样式、事件绑定
  • 如何积极压榨性能

以上就是虚拟DOM基本涉及的问题,如果觉得我分享对你有点用,点个关注

相关文章
评论
新版评论功能开发中
头条推荐
最新资讯