实现简易版react中createElement和render方法
function createElement(type, config, children) {
// 1. 创建一个对象
// 2.根据参数config修改这个对象
// 3.把children参数作为对象中props中的一个属性
let virtureDOM = {};
virtureDOM.type = type;
virtureDOM.ref = config.ref || null;
virtureDOM.key = config.key || null; let props = {}; // 虚拟dom的props
for (const attr in config) { // 遍历config 把除去ref和key的属性值复制到props中
if (attr === 'key' || attr === 'ref') continue;
else props[attr] = config[attr];
} const childrenLength = arguments.length - 2;// create可以传多个参数 第三个开始被认为是children
if (childrenLength === 1) {
props.children = children; // 如果只有一个 那么children就是第三个参数
} else if (childrenLength > 1) {
let childArray = Array(childrenLength); // 如果不止一个,就存入childArray数组中
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
props.children = childArray;
} virtureDOM.props = props;
return virtureDOM;
} // 把创建的对象转为真实DOM元素最后插入到页面中
function render(virtureDOM, container, callback) {
let { type, props } = virtureDOM || {};
let realDom = document.createElement(type); for (let attr in props) {
if (!props.hasOwnProperty(attr)) break; // 如果不是私有属性 直接跳出 说明已经遍历到原型上了
if (!props[attr]) continue; // 如果这个attr没有有效值,那么继续找下一个
const val = props[attr];
// 处理classname变成class
if (attr === 'className') realDom.setAttribute('class', val); else if (attr === 'children') { // 处理children
if (typeof val === 'string') { // 如果只有一个字符串children 那么直接渲染text出来
let text = document.createTextNode(val);
realDom.appendChild(text);
}
else if (val instanceof Array) { // 如果children是数组, 那么就得遍历这个数组分情况再渲染
for (let i = 0; i < val.length; i++) {
if (typeof val[i] === 'string') {
let text = document.createTextNode(val[i]);
realDom.appendChild(text);
} else {
render(val[i], realDom);
}
}
}
else { // 如果children只有一个且不是数组也不是字符串 那么应该是createElement出来的虚拟dom。递归
render(val, realDom);
}
} else if (attr === 'style') { // 处理style属性
if (val === '') continue; // style 有可能值为空字符串
for (let sty in val) {
if (val.hasOwnProperty(sty)) realDom['style'][sty] = val[sty];
}
} else realDom.setAttribute(attr, val); // 基于setAttribute可以让设置的属性表现在html的结构上
}
container.appendChild(realDom);
callback && callback();
} const virtureDom2 = createElement('span',
{}, 'age is 18!'); const virtureDom = createElement('div',
{
id: 'box',
className: 'lp',
style: { color: 'red' },
key: 12,
ref: 'refs'
}, 'my name is LanPang ', virtureDom2); render(virtureDom, document.getElementById('root'), () => console.log('finish'));
实现简易版react中createElement和render方法的更多相关文章
- React中ref的使用方法
React中ref的使用方法 在react典型的数据流中,props传递是父子组件交互的唯一方式:通过传递一个新的props值来使子组件重新re-render,从而达到父子组件通信.当然,就像reac ...
- react中的children使用方法
使用过vue的小伙伴都知道vue中有个slot,也就是插槽,作用就是占位,那么再react中可以使用children来替代 父组件 render(){ return( <div> < ...
- react中常用的一些方法
React.createClass:创建一个ReactClass(组件类),参数是一个对象且必须带有 render 属性方法,该方法必须返回一个封闭的容器(容器内可以有其它不限结构的容器)或 null ...
- 聊一聊React中虚拟DOM
1. 什么是虚拟 DOM 在 React 中实际上是 render 函数中return 的内容会生成 DOM,return 中的内容由两部分组成,一部分是 JSX ,另一部分就是 state 中的数据 ...
- react中的setState的使用和深入理解
前端框架从MVC过渡到MVVM.从DOM操作到数据驱动,一直在不断的进步着,提升着, angular中用的是watcher对象,vue是观察者模式,react就是state了,他们各有各的特点,没有好 ...
- React中的事件处理为什么要bind this?
个人总结: 问: 请给我讲一下React中的事件处理为什么要bind this? 答: 好的,比如说我写了一个类组件,有个onClick属性 ,onClick={ this.fun },如果不bind ...
- React中的State与Props
一.State 1.什么是 state 一个组件的显示形态可以由数据状态和外部参数决定,其中,数据状态为 state,外部参数为 props 2.state 的使用 组件初始化时,通过 this.st ...
- React中setState的怪异行为 ——setState没有即时生效
setState可以说是React中使用频率最高的一个函数了,我们都知道,React是通过管理状态来实现对组件的管理的,当this.setState()被调用的时候,React会重新调用render方 ...
- react中怎么写css样式?
JSX基本语法中关于react如何写css样式主要有三种方法 1.基于class --(className) 基于className ,通过className在style中给该class名的DOM元素 ...
随机推荐
- __call__ 与__init__,object 参数的使用
class test1: ###有object是可读可写 def __init__(self): ##__init__表示构造函数.__call__是析构函数. self.__pravite = &q ...
- ios]企业开发者账号申请
1. 先打电话到“华夏邓白氏公司”(上海:400-820-3536 北京:400-810-3531 广州:800-830-9032),我打的是北京分部的电话,就说自己因为申请apple开发者账号,需要 ...
- 填坑!线上Presto查询Hudi表异常排查
1. 引入 线上用户反馈使用Presto查询Hudi表出现错误,而将Hudi表的文件单独创建parquet类型表时查询无任何问题,关键报错信息如下 40931f6e-3422-4ffd-a692-6c ...
- Create First Application
Node.js创建第一个应用 Node.js开发的目的就是为了用JavaScript编写Web服务器程序, 在使用Node.js时,不仅仅是在实现一个应用,同时还实现了整个HTTP服务器.在创建Nod ...
- SQL——TOP、IN、BETWEEN AND、IS NULL和IS NOT NULL
TOP子句 - 用于规定要返回的记录的数目.并不是所有数据库都支持TOP子句. 语法: SQLServer:SELECT TOP number|percent columnName ...
- HTTP 规范中的那些暗坑
HTTP 协议可以说是开发者最熟悉的一个网络协议,「简单易懂」和「易于扩展」两个特点让它成为应用最广泛的应用层协议. 虽然有诸多的优点,但是在协议定义时因为诸多的博弈和限制,还是隐藏了不少暗坑,让人一 ...
- XMLHttpRequest实现Ajax &数据格式JSON
GET请求 index <%@ page language="java" contentType="text/html; charset=utf-8" p ...
- 图解MySQL索引(二)—为什么使用B+Tree
失踪人口回归,近期换工作一波三折,耽误了不少时间,从今开始每周更新~ 索引是一种支持快速查询的数据结构,同时索引优化也是后端工程师的必会知识点.各个公司都有所谓的MySQL"军规" ...
- winxp无法访问win10教育版共享资源的问题处理
一.问题来源: dell5460笔记本上一个winxp系统虚拟机,访问一台lenovoT470笔记本win10教育版系统上的共享资源(使用命令行方式:net use s: \\172.18.45.10 ...
- Java实现 LeetCode 581 最短无序连续子数组(从两遍搜索找两个指针)
581. 最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: ...