vnode.js
export default function vnode(sel,data,children,text,elm){
//key值是标签的唯一标识,在data.key中,这里获取一下key
const key = data === undefined ? undefined : data.key
return { sel, data, children, text, elm, key };
}
h函数各个参数 sel:{String | Object | Function} 必须 一个 HTML 标签名、一个组件、一个异步组件、或一个函数式组件。
data:{Object} 可选 与 attribute、prop 和事件相对应的对象。
key:该值在data中,虚拟DOM的唯一标识 可选
text:{String} 可选
children:(h() | {}) 可选
elm:表示是否上树 h函数的流程 h函数必定传的有一个值就是sel,表示的标签名称,比如div h函数传值的时候先判断第三个参数children是否有值,如果有值则进行判断 1.children是数组,说明是子元素 2.children是字符串,说明是text参数中的内容,也就是标签中的文字 3.children有值,且children.sel有值,说明是子元素,只不过不是数组的形式,需要将其转换成数组的形式在添加 h函数传值的时候没有第三个参数children,有第二个参数data,这时再根据第三个参数判断的形式进行判断 1.data是数组,说明是子元素 2.data是字符串,说明是text参数中的内容,也就是标签中的文字 3.data有值,且data.sel有值,说明是子元素,只不过不是数组的形式,需要将其转换成数组的形式在添加 4.如果以上三种都不是则说明data中传的值是与 attribute、prop 和事件相对应的对象,将其直接赋值给data h函数判断children中的值是否存在text,就是标签中的文字,如果有则只传children,其他的值都为undefined h函数最后进行判断是否是svg标签 h.js
// 引入vnode
import vnode from "./vnode";
import is from './is'
function addNS(data,children,sel){
data.ns = "http://www.w3.org/2000/svg";
if (sel !== "foreignObject" && children !== undefined) {
for (let i = 0; i < children.length; ++i) {
const child = children[i];
if (typeof child === "string")
continue;
const childData = child.data;
if (childData !== undefined) {
addNS(childData, child.children, child.sel);
}
}
}
}
export default function h(sel,b,c){
// 定义返回值
let data = {};
let children;
let text;
let i;
//如果c!==undefined说明children传值了
if(c!==undefined){
if(b!==null){
//如果b不是null则将b赋值给data
data = b;
}
//判断c是children还是text
if(is.array(c)){
//c为children时,将c赋值给children
children = c
}else if(is.primitive(c)){
//c为输入的内容,将c转换成字符串赋值给text
text = c.toString();
}else if(c&&c.sel){
//c为一个子元素,并不是以数组的形式写上的,则将c变成数组的形式赋值给children
children = [c];
}
}else if(b!==undefined&&b!==null){
//如果c为undefined了就该判断c前面的b是否是undefined或null了
//判断b是children还是data
if(is.array(b)){
//这里说明b是children
children = b;
}else if(is.primitive(b)){
//这里判断b是text
text = b.toString()
}else if(b&&b.sel){
//这里判断是否是单个h函数,不是数组形式的children
children = [b];
}else{
//这里说明b是data
data = b;
}
}
//判断children数组中的数据是否是text
if(children !== undefined){
for(i = 0;i<children.length;++i){
if(is.primitive(children[i])){
//如果是字符串则只传text
children[i]=vnode(undefined,undefined,undefined,children[i].undefined)
}
}
}
if (sel[0] === "s" &&
sel[1] === "v" &&
sel[2] === "g" &&
(sel.length === 3 || sel[3] === "." || sel === "#")) {
//判断是否时svg标签
addNS(data,children,sel)
}
//这里返回的最后一个参数为undefined,是因为还没有上树,elm为undefined
return vnode(sel,data,children,text,undefined);
}
|