React.js中JSX的原理与关键实现
在开始开发之前,我们需要创建一个空项目文件夹。
安装
- 初始化
npm init -y
2.安装webpack相关依赖
npm install webpack webpack-cli -D
- 安装babel-loader相关依赖
npm install babel-loader @babel/core @babel/preset-env -D
- 安装jsx支持依赖
npm install @babel/plugin-transform-react-jsx -D
配置
-
在根目录下创建main.js文件
此文件为入口文件。 -
在项目根目录下创建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
}
}
- 创建一个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文件就可以看到效果了。
作者:Vam的金豆之路
主要领域:前端开发
我的微信:maomin9761
微信公众号:前端历劫之路