/**
* @method createElement
* @param type {string}
* @param props {Object}
* @param children {string}
*/
let createElement = (type, props, ...children) => { props = props || {};
let obj = {
type: null,
props: {
children: children.length <= 1 ? (children[0] || '') : children
},
key: null,
ref: null,
};
obj = {...obj, type, props: {...props, children}};
// eslint-disable-next-line no-unused-expressions
'key' in obj.props ? (obj.key = obj.props.key, obj.props.key = undefined) : null;
// eslint-disable-next-line no-unused-expressions
'ref' in obj.props ? (obj.ref = obj.props.ref, obj.props.ref = undefined) : null;
return obj;
}; /**
* @method render
* @param obj {Object}
* @param container {elementNode}
* @param callback {function}
*/
let render = (obj, container, callback) => { let {type, props} = obj || {},
newElement = document.createElement(type); for (const attr in props) { if (!props.hasOwnProperty(attr)) break; // 不是私有的直接结束遍历
if (!props[attr]) continue; // 如果当前属性没有值,直接不处理即可
let value = props[attr]; // className
if (attr === 'className') {
newElement.setAttribute('class', value);
continue
} // style
if (attr === 'style') {
// 如果style为空支付串,不处理
if (value === '') continue;
for (const styleKey in value) {
if (value.hasOwnProperty(styleKey)) {
newElement['style'][styleKey] = value[styleKey];
}
}
continue
} // children
if (attr === 'children') { // 先将其转换为数组,后期直接操作数组即可
// eslint-disable-next-line no-unused-expressions
!(value instanceof Array) ? value = [value] : null;
value.forEach((item, index) => {
if (typeof item === "string") {
let text = document.createTextNode(item);
newElement.appendChild(text) } else {
render(item, newElement);
}
});
continue
}
newElement.setAttribute(attr, value); // 基于setAttribute设置的属性,可以变现在HTML的结构上
} container.appendChild(newElement);
callback && callback();
}; let elementNode = createElement(
'div',
{id: 'container', ref: 'main', key: new Date()},
createElement(
'hr'
),
createElement(
'div',
{id: 'header'},
'头部'
),
createElement(
'hr'
),
createElement(
'div',
{id: 'main'},
'主体内容'
),
createElement(
'hr'
),
createElement(
'div',
{id: 'footer'},
'脚注'
),
); // eslint-disable-next-line no-undef
render(elementNode, root, _ => console.log('ok'))

简单实现react中虚拟DOM渲染的更多相关文章

  1. react中虚拟dom的diff算法

    .state 数据 .jsx模板 .生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM) ['div', {id:'abc'}, ['span', {}, 'hello world']] ...

  2. 聊一聊React中虚拟DOM

    1. 什么是虚拟 DOM 在 React 中实际上是 render 函数中return 的内容会生成 DOM,return 中的内容由两部分组成,一部分是 JSX ,另一部分就是 state 中的数据 ...

  3. react中虚拟DOM的基本概念

    react中的核心概念 1.DOM的本质是什么: 浏览器中的概念,用js对象来表示页面上的元素,并提供操作DOM对象的API 2.什么事react中的虚拟DOM:是框架中的概念,是程序员用js对象来模 ...

  4. react中虚拟DOM

    简单来说虚拟DOM就是一个js对象,相对于真实dom来做比较更节约性能,虚拟DOM执行过程如下

  5. 【React自制全家桶】二、分析React的虚拟DOM和Diff算法

    一.React如何更新DOM内容: 1.  获取state 数据 2.  获取JSX模版 3.  通过数据 +模版结合,生成真实的DOM, 来显示,以下行代码为例(简称代码1) <div id= ...

  6. React的虚拟DOM

    ReactJs的一大特点就是引进了虚拟dom(Virtual DOM)的概念.为什么我们需要Virtual DOM,Virtual DOM给我们带来了什么优势. 首先我们要了解一下浏览器的工作流. 当 ...

  7. vue2.0的虚拟DOM渲染

    1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...

  8. 【译】在React中实现条件渲染的7种方法

    原文地址:https://scotch.io/tutorials/7-ways-to-implement-conditional-rendering-in-react-applications 借助R ...

  9. React virtual DOM explained in simple English/简单语言解释React的虚拟DOM

    初学React,其中一个很重要的概念是虚拟DOM,看了一篇文章,顺带翻译一下. If you are using React or learning React, you must have hear ...

随机推荐

  1. python numpy.array插入一行或一列

    numpy.array插入一行或一列 import numpy as np a = np.array([[1,2,3],[4,5,6],[7,8,9]]) b = np.array([[0,0,0]] ...

  2. node.js的iconv模块----在linux上读取windows编码文件

    有时候我们在windows上会保存一些中文文字信息文件,然而由于编码集的差异,这文件在linux上显示为乱码,其中一种解决方法是node.js的iconv模块 var fs = require('fs ...

  3. SpringBoot启动过程原理(转)

    1.1 Springboot启动: @SpringBootApplication public class ServerApplication { public static void main(St ...

  4. 【极大化剪枝】Power Hungry Cows-C++【没有用A*!】【超级简单!】

    Description小KITTY想要快速计算整数P的幂 (1 <= P <=10,000),它们需要你的帮助.因为计算极大数的幂,所以它们同一时间仅能使用2个存储器,每个存储器可记录某个 ...

  5. MySQL组提交(group commit)

    MySQL组提交(group commit) 前提: 以下讨论的前提 是设置MySQL的crash safe相关参数为双1: sync_binlog=1 innodb_flush_log_at_trx ...

  6. 內嵌html字符串顯示

    前端:System.Web.HttpUtility.HtmlEncode()            @Html.Raw(htmlStr) 後端:System.Net.WebUtility.HtmlDe ...

  7. java上传文件夹

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用.此控件PC全平台支持包括mac,linux系统的文件上传,文章末尾将附上控件下载与教程链接 ...

  8. bzoj3508: 开灯

    题目链接 题解 设\(b[i]=a[i]\ xor\ a[i+1]\) 我们可以发现,修改只会改变\(b[l-1]\)和\(b[r]\) 然后发现\(b[i]=1\)的点最多\(2*k\)个 状压\( ...

  9. rep stos ptr dword es:[edi]

    今天读代码时,忽然跳出如下一条指令==>>汇编代码: rep stos dword ptr es:[edi] 在网上查了相关资料显示:/************************** ...

  10. vscode设置VUE eslint开发环境

    我的使用vscode开发VUE的常用设置 1.安装插件 ESLint Vetur Beautify Prettier - Code formatter Auto Rename Tag -重命名标签,闭 ...