使用JSX 建立组件 Parser(解析器)开发的示例(4)

这里第二个参数为什么是 null 呢?其实第二个参数是用来传属性列表的。如果我们在 main.js 里面的 div 中加入一个 id="a" ,我们来看看最后编译出来会有什么变化。

使用JSX 建立组件 Parser(解析器)开发的示例

我们就会发现第二个参数变成了一个以 Key-Value 的方式存储的JavaScript 对象。到这里如果我们想一下,其实 JSX 也没有那么神秘,它只是把我们平时写的 HTML 通过编译改写成了 JavaScript 对象,我们可以认为它是属于一种 “[[语法糖]]”。

但是 JSX 影响了代码的结构,所以我们一般也不会完全把它叫作语法糖。

接下来我们来写一些更复杂一些的 JSX,我们给原本的 div 加一些 children 元素。

function createElement() { return; } let a = ( <div> <span></span> <span></span> <span></span> </div> );

最后我们执行以下 webpack 打包看看效果。

使用JSX 建立组件 Parser(解析器)开发的示例

在控制台中,我们可以看到最后编译出来的结果,是递归的调用了 createElement 这个函数。这里其实已经形成了一个树形的结构。

父级就是第一层的 div 的元素,然后子级就是在后面当参数传入了第一个 createElement 函数之中。然后因为我们的 span 都是没有属性的,所以所有后面的 createElement 的第二个参数都是 null。

根据我们这里看到的一个编译结果,我们就可以分析出我们的 createElement 函数应有的参数都是什么了。

第一个参数 type —— 就是这个标签的类型

第二个参数 attribute —— 标签内的所有属性与值

剩余的参数都是子属性 ...children —— 这里我们使用了 JavaScript 之中比较新的语法 ...children 表示把后面所有的参数 (不定个数) 都会变成一个数组赋予给 children 变量

那么我们 createElement 这个函数就可以写成这样了:

function createElement(type, attributes, ...children) { return; }

函数我们有了,但是这个函数可以做什么呢?其实这个函数可以用来做任何事情,因为这个看起来长的像 DOM API,所以我们完全可以把它做成一个跟 React 没有关系的实体 DOM。

比如说我们就可以在这个函数中返回这个 type 类型的 element 元素。这里我们把所有传进来的 attributes 给这个元素加上,并且我们可以给这个元素挂上它的子元素。

创建元素我们可以用 createElement(type),而加入属性我们可以使用 setAttribute(),最后挂上子元素就可以使用 appendChild()。

function createElement(type, attributes, ...children) { // 创建元素 let element = document.createElement(type); // 挂上属性 for (let attribute in attributes) { element.setAttribute(attribute); } // 挂上所有子元素 for (let child of children) { element.appendChild(child); } // 最后我们的 element 就是一个节点 // 所以我们可以直接返回 return element; }

这里我们就实现了 createElement 函数的逻辑。最后我们还需要在页面上挂載上我们的 DOM 节点。所以我们可以直接挂載在 body 上面。

// 在 main.js 最后加上这段代码 let a = ( <div> <span></span> <span></span> <span></span> </div> ); document.body.appendChild(a);

这里还需要注意的是,我们的 main.html 中没有加入 body 标签,没有 body 元素的话我们是无法挂載到 body 之上的。所以这里我们就需要在 main.html 当中加入 body 元素。

<body></body> <script src="https://www.jb51.net/dist/main.js"></script>

好,这个时候我们就可以 webpack 打包,看一下效果。

使用JSX 建立组件 Parser(解析器)开发的示例

Wonderful! 我们成功的把节点生成并且挂載到 body 之上了。但是如果我们的 div 里面加入一段文字,这个时候就会有一个文本节点被传入我们的 createElement 函数当中。毋庸置疑,我们的 createElement 函数以目前的逻辑是肯定无法处理文本节点的。

接下来我们就把处理文本节点的逻辑加上,但是在这之前我们先把 div 里面的 span 标签删除,换成一段文本 “hello world”。

let a = <div>hello world</div>;

在我们还没有加入文本节点的逻辑之前,我们先来 webpack 打包一下,看看具体会报什么错误。

使用JSX 建立组件 Parser(解析器)开发的示例

使用JSX 建立组件 Parser(解析器)开发的示例

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsddys.html