实现简易版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元素 ...
随机推荐
- ABAP基础4:模块化
子程序定义 以form开始,以endform结束,用perform语句调用,from语句可以在程序内部/外部,perform一定要写在前面 perform. from. 子程序模块 endform. ...
- MYSQL mysql.user表中权限对应的解释
命令标识 授权表中对应的列 说明 CREATE Create_priv 创建数据库.表或索引 CREATE TEMPORARY TABLES Create_tmp_table_priv 创建临时数据表 ...
- SpringCloud异常处理统一封装我来做-使用篇
SpringCloud异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单 ...
- zoj3997网络流+数学
题目大意就是每个人都有自己喜欢的座位编号,喜欢的编号是要x的倍数就好,(1<=x<=10)一共10种情况,每种情况的人的数目不一样. 给你一个n,代表有编号1-n这n个座位,问最多能满足多 ...
- 枚举 转化为可行性判定问题 网络流 poj3189
Steady Cow Assignment Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6914 Accepted: ...
- 十、理解JavaBean
1. 理解Bean 1.JavaBean本身就是一个类,属于Java的面向对象编程. 2.在JSP中如果要应用JSP提供的Javabean的标签来操作简单类的话,则此类必须满足如下的开发要求: (1) ...
- Java——分布式
分布式编程技术的基本思想:客户计算机产生一个请求,然后将这个请求通过网络发送到服务器.服务器处理这个请求,并发送回一个针对该客户端的响应,供客户端进行分析.客户端和服务端之间用代理进行通讯,客户端调用 ...
- [Python基础]004.语法(3)
语法(3) 方法 定义 调用 参数 返回 模块 引入模块 写模块 模块名称 dir() 方法 定义 语法 def 方法名(参数): 返回值 return 没有指定返回值的方法,默认返回空值 None ...
- Java IO(一)概述
Java IO(一)概述 一.IO概述 (一).介绍 在Java中,所有的数据都是通过流读写的,Java提供了IO来处理设备之间的数据传输,Java程序中,对于数据的输入/输出操作 都是以“流”的方式 ...
- Centos8 删除了yum.repos.d 下面的文件
原文: https://www.cnblogs.com/junjind/p/9016107.html centos-release-8.1-1.1911.0.9.el8.x86_64 找到 https ...