React.js中JSX的原理与关键实现

Jacquelyn38
• 阅读 1453

在开始开发之前,我们需要创建一个空项目文件夹。

安装

  1. 初始化
npm init -y  

2.安装webpack相关依赖

npm install webpack webpack-cli -D  
  1. 安装babel-loader相关依赖
npm install babel-loader @babel/core @babel/preset-env -D  
  1. 安装jsx支持依赖
npm install @babel/plugin-transform-react-jsx -D  

配置

  1. 在根目录下创建main.js文件 此文件为入口文件。

  2. 在项目根目录下创建webpack.config.js

module.exports={  
  entry:{  
    main:'./main.js'  
  },  
  module:{  
    rules:[  
      {  
        test:/\.js$/,  
        use:{  
          loader:'babel-loader',  
          options:{  
            presets:['@babel/preset-env'],  
            plugins:[['@babel/plugin-transform-react-jsx',{pragma:'createElement'}]] // 自定义设置pragma参数,我也可以设置为我的名字:maomin  
          }  
        }  
      }  
    ]  
  },  
  mode:'development',  
  optimization:{  
    minimize: false  
  }  
}  
  1. 创建一个reactJsx.js文件 此文件为主要逻辑文件。

开发

reactJsx.js

// 封装创建Dom节点  
class ElementWrapper {  
  constructor(type) {  
    this.root = document.createElement(type);  
  }  
  setAttibute(name, value) {  
    this.root.setAttibute(name, value);  
  }  
  appendChild(component) {  
    this.root.appendChild(component.root);  
  }  
}  

// 封装插入文本节点  
class TextWrapper {  
  constructor(content) {  
    this.root = document.createTextNode(content);  
  }  
}  
// 组件  
export class Component {  
  constructor() {  
    this.props = Object.create(null); // 创建一个原型为null的空对象  
    this.children = [];  
    this._root = null;  
  }  
  setAttribute(name, value) {  
    this.props[name] = value;  
  }  
  appendChild(component) {  
    this.children.push(component);  
  }  
  get root() { // 取值  
    if (!this._root) {  
      this._root = this.render().root;  
    }  
    return this._root;  
  }  
}  
// 创建节点,createElement对照 webapck.config.js 中pragma参数。  
export function createElement(type, attributes, ...children) {  
  let e;  
  if (typeof type === "string") {  
    e = new ElementWrapper(type);  
  } else {  
    e = new type();  
  }  
  for (let p in attributes) { // 循环属性  
    e.setAttribute(p, attributes[p]);  
  }  
  let insertChildren = (children) => {  
    for (let child of children) {  
      if (typeof child === "string") {  
        child = new TextWrapper(child);  
      }  
      if (typeof child === "object" && child instanceof Array) {  
        insertChildren(child); // 递归  
      } else {  
        e.appendChild(child);  
      }  
    }  
  };  
  insertChildren(children);  
  return e;  
}  

// 添加到Dom中  
export function render(component, parentElement) {  
  parentElement.appendChild(component.root);  
}  

main.js

import {createElement,Component,render} from './reactJsx.js'  

class MyComponent extends Component {  
  render(){  
    return <div>  
      <h1>maomin</h1>  
      {this.children}  
    </div>  
  }  
}  

render(<MyComponent id="name" class="age">  
  <div>xqm</div>  
  <div>my girlfriend</div>  
</MyComponent>,document.body)  

执行

npx webpack  

在dist文件夹下创建html文件,然后引入main.js,打开html文件就可以看到效果了。

React.js中JSX的原理与关键实现

  • 欢迎关注我的公众号前端历劫之路

  • 回复关键词电子书,即可获取12本前端热门电子书。

  • 回复关键词红宝书第4版,即可获取最新《JavaScript高级程序设计》(第四版)电子书。

  • 关注公众号后,点击下方菜单即可加我微信,我拉拢了很多IT大佬,创建了一个技术交流、文章分享群,期待你的加入。

  • 作者:Vam的金豆之路

  • 微信公众号:前端历劫之路

React.js中JSX的原理与关键实现

- END -

React.js中JSX的原理与关键实现

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/x4qwEcSZ0vG4EaHiA3O0hA,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
2年前
使用node.js如何简单快速的搭建一个websocket聊天应用
初始化项目npm init安装nodejswebsocketnpm install nodejswebsocket创建并编辑启动文件创建一个名为app.js文件,并且编辑它。var ws  require("nodejswebsocket");console.log("开始建立连接...")var user1,user2,user1
Souleigh ✨ Souleigh ✨
2年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这