虚似DOM(Virtual Document Object

lxf2023-05-20 00:52:06

什么是VDOM

虚似DOM(Virtual Document Object Model)一般是指JavaScript目标组成的一棵“树”,它能够表明一个DOM的结构分析,而且能够轻松的被改动、拷贝和分析。

在传统页面渲染中,当页面元素变化时,电脑浏览器会再次搭建全部DOM树,而且再次3D渲染全部网页页面。这一过程十分消耗特性,特别是在页面元素许多的情形下,会导致显著页面卡死和延迟时间。虚似DOM的确立,便是针对这种情况。

虚似DOM使用了一种巧妙地3D渲染方法,它先把全部DOM树以JavaScript对象方式存放内存中,再对这一“虚似DOM”来操作,接着再把它转换成具体的DOM树,以此来实现页面渲染。这种方法能够避免频繁的开展DOM实际操作,从而提高页面渲染效率。

虚似DOM还具备另一个重要的优势,便是适用组件化开发。在虚拟DOM中,每一个部件都是一个单独的虚似DOM连接点,部件相互间能够容易地传送数据人物事件。这种方法让开发人员更为致力于元件的完成,从而提高程序代码可复用性和可维护性

虚似DOM的完成

建立虚似DOM连接点:

虚似DOM连接点一般用JavaScript目标来描述。比如:

const element = {
 type: "div",
 props: {
  className: "foo",
  children: [{ type: "p", props: { children: "Hello, world!" } }],
  },
};

这儿创建了一个div连接点,而且它的props属性包括一个className,以及一个包括一个p节点children特性二维数组。

将虚似DOM连接点转换成真实DOM连接点:

将虚似DOM连接点转换成真实DOM连接点必须运用document.createElement()函数公式来达到。比如:

function createElement(node) {
 if (typeof node === "string") {
  return document.createTextNode(node);
  }
 const element = document.createElement(node.type);
 node.props.children.forEach((child) => {
  element.appendChild(createElement(child));
  });
 return element;
}
const rootElement = createElement(element);

这儿用createElement()函数公式将虚似DOM连接点转化成了真实DOM连接点。

较为新老虚似DOM连接点:

较为新老虚似DOM连接点,找到差别,并把差别保留下来。较为可以采取深度优先遍历的形式,逐一较为节点种类、特性和子节点。比如:

function diff(oldNode, newNode) {
  if (oldNode.type !== newNode.type) {
   return {
    type: 'NODE_TYPE_CHANGED',
    payload: newNode
   };
  }
  if (typeof oldNode !== typeof newNode) {
   return {
    type: 'NODE_CHANGED',
    payload: newNode
   };
  }
  if (typeof oldNode === 'string' && oldNode !== newNode) {
   return {
    type: 'NODE_CHANGED',
    payload: newNode
   };
  }
  const propsDiff = diffProps(oldNode.props, newNode.props);
  const childrenDiff = diffChildren(oldNode.props.children, newNode.props.children);
  if (propsDiff || childrenDiff) {
   return {
    type: 'NODE_PROPS_CHANGED',
    payload: {
     props: propsDiff,
     children: childrenDiff
    }
   }
  }
  return null;
}
function diffProps(oldProps, newProps) {
  // 较为props属性
}
function diffChildren(oldChildren, newChildren) {
  // 较为子节点
}

依据差别升级真实DOM连接点:

依据前边较为出去的差别信息内容,对具体的DOM连接点进行更新。比如:

function patch(node, patches) {
 // 依据差别数据更新连接点
 patches.forEach((patch) => {
  if (patch.type === "NODE_TYPE_CHANGED") {
   const newNode = createElement(patch.payload);
   node.parentNode.replaceChild(newNode, node);
   }
  if (patch.type === "NODE_CHANGED") {
   node.nodeValue = patch.payload;
   }
  if (patch.type === "NODE_PROPS_CHANGED") {
   patch.props.forEach((propPatch) => {
    if (propPatch.type === "SET_PROP") {
     node.setAttribute(propPatch.key, propPatch.value);
     }
    if (propPatch.type === "REMOVE_PROP") {
     node.removeAttribute(propPatch.key);
     }
    });
   patch.children.forEach((childPatch) => {
    patch(node.childNodes[childPatch.index], childPatch);
    });
   }
  });
}
const patches = diff(oldNode, newNode);
patch(rootElement, patches);

这儿用patch()函数公式依据差别数据更新具体的DOM连接点。 以上就是虚似DOM的基本完成流程,具体的完成很有可能还要考虑到一些突发情况,比如元件的状态更新、事故处理等。

本站是一个以CSS、JavaScript、Vue、HTML为中心的前端开发技术网址。我们的使命是为众多前端工程师者提供全方位、全方位、好用的前端工程师专业知识和技术服务。 在网站上,大家可以学到最新前端开发技术,掌握前端工程师最新发布的趋势和良好实践。大家提供大量实例教程和实例,让大家可以快速上手前端工程师的关键技术和程序。 本站还提供了一系列好用的工具软件,帮助你更高效地开展前端工程师工作中。公司提供的一种手段和软件都要经过精心策划和改进,能够帮助你节约时间精力,提高研发效率。 此外,本站还拥有一个有活力的小区,你可以在社区里与其它前端工程师者沟通交流技术性、交流经验、处理问题。我们坚信,街道的能量能够帮助你能够更好地进步与成长。 在网站上,大家可以寻找你需要的一切前端工程师网络资源,使您成为一名更加出色的网页开发者。欢迎你添加我们的大家庭,一起探索前端工程师的无限潜能!