对 virtual DOM 的理解
- React.createElement 函数所返回的就是一个虚拟 DOM
- 虚拟 DOM 就是一个描述真实 DOM 的纯 JS 对象
import React from 'react'
let virtualDOM = React.createElement('div', {id: 'A1', key: 'A1'}, React.createElement('div', {id: 'B1', key: 'B1'}, B1), React.createElement('div', {id: 'B2', key: 'B2'}, B2)
const symbolFor = Symbol.for;
const REACT_ELEMENT_TYPE = symbolFor('react.element');
/**
*
* @param {*} type 元素的类型
* @param {*} config 配置对象
* @param {*} children child
*/
const RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true
}
export function createElement(type, config, children) {
const props = {};
// key 用来标示一个稳定元素
let key = null;
if (config !== null) {
key = config.key;
}
for (let propName in config) {
if (!RESERVED_PROPS.hasOwnProperty(propName)) {
props[propName] = config[propName];
}
}
const childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
const childArray = Array(childrenLength);
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i+2]
}
props.children = childArray;
}
// React.createElement 方法返回的是一个普通的 js 对象,它可以描述元素的样子,它就是所谓的虚拟 dom
// 虚拟 dom 是跨平台的,跟平台无关
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props
}
return element;
}
/**
* children
* 有可能是一个元素,可能是个字符串,可能是一个数字,null
* 有可能有一个儿子,也有可能没有儿子,也有可能有多个儿子
* props.children = null | string | number | React 元素
*
*/
有什么优点
- 处理了浏览器兼容性问题,避免了用户操作真实 dom
- 内容经过 XSS 处理,可以防范 XSS 攻击
- 容易实现跨平台开发 android、ios、vr 应用
- 更新的时候可以实现差异化更新,减少更新 dom 操作
有什么缺点
- 虚拟 dom 需要消耗额外的内存
- 在初次渲染的时候,不一定更快,在更新的时候,更新的元素内容比较少,它可以实现精准的定量更新,不需要把全部的 dom 元素删除重添加
- 虚拟 dom 的优势肯定不是更快
为什么要用 Virtual DOM
因为浏览器的标准就是把 DOM 设计得非常的复杂。如果我们频繁的操作 DOM,会产生一定的性能问题,我们通过操作一个简单的,抽象的 DOM,最后将差异尽可能一次性的 patch 到真实的 DOM 上,这样会减少很多性能问题
网友评论