这里第二个参数为什么是 null 呢?其实第二个参数是用来传属性列表的。假如我们在 main.js 内里的 div 中插手一个 id="a" ,我们来看看最后编译出来会有什么变革。
我们就会发明第二个参数酿成了一个以 Key-Value 的方法存储的JavaScript 工具。到这里假如我们想一下,其实 JSX 也没有那么神秘,它只是把我们平时写的 HTML 通过编译改写成了 JavaScript 工具,我们可以认为它是属于一种 “[[语法糖]]”。
可是 JSX 影响了代码的布局,所以我们一般也不会完全把它叫作语法糖。
接下来我们来写一些更巨大一些的 JSX,我们给原本的 div 加一些 children 元素。
function createElement() { return; } let a = ( <div> <span></span> <span></span> <span></span> </div> );
最后我们执行以下 webpack 打包看看结果。
在节制台中,我们可以看到最后编译出来的功效,是递归的挪用了 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 打包,看一下结果。
Wonderful! 我们乐成的把节点生成而且挂載到 body 之上了。可是假如我们的 div 内里插手一段文字,这个时候就会有一个文本节点被传入我们的 createElement 函数傍边。毋庸置疑,我们的 createElement 函数以今朝的逻辑是必定无法处理惩罚文本节点的。
接下来我们就把处理惩罚文本节点的逻辑加上,可是在这之前我们先把 div 内里的 span 标签删除,换成一段文本 “hello world”。
let a = <div>hello world</div>;
在我们还没有插手文本节点的逻辑之前,我们先来 webpack 打包一下,看看详细会报什么错误。