vue3中 h()函数

看结果

 利用h()函数时可以传节点标签,样式,以及节点内容

//类型判断函数
const isObject = (val) => val !==null && typeof val === 'object'
const isString = (val) => typeof val === 'string'
const isFunction = (val) => typeof val === 'function';
const isArray = Array.isArray

const InternalObjectKey = `__vInternal`;
//?
function isVNode(value) {
    return value ? value.__v_isVNode === true : false;
}

let vnodeArgsTransformer;
let currentRenderingInstance = null;
let currentScopeId = null;
let currentBlock = null;
let isBlockTreeEnabled = 1;
const Text = Symbol('Text');
//?
function isClassComponent(value) {
    return isFunction(value) && '__vccOpts' in value;
}

const normalizeKey = ({ key }) => key != null ? key : null;
const normalizeRef = ({ ref }) => {
    return (ref != null
        ? isString(ref) || isRef(ref) || isFunction(ref)
            ? { i: currentRenderingInstance, r: ref }
            : ref
        : null);
};

function createTextVNode(text = ' ', flag = 0) {
    return createVNode(Text, null, text, flag);
}

function normalizeChildren(vnode, children) {
    let type = 0;
    const { shapeFlag } = vnode;   //值为 1
    //34 -74 类型判断 传入的 string类型数据 不执行
    if (children == null) {
        children = null;
    }
    else if (isArray(children)) {
        type = 16 /* ARRAY_CHILDREN */;
    }
    else if (typeof children === 'object') {
        if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
            // Normalize slot to plain children for plain element and Teleport
            const slot = children.default;
            if (slot) {
                // _c marker is added by withCtx() indicating this is a compiled slot
                slot._c && (slot._d = false);
                normalizeChildren(vnode, slot());
                slot._c && (slot._d = true);
            }
            return;
        }
        else {
            type = 32 /* SLOTS_CHILDREN */;
            const slotFlag = children._;
            if (!slotFlag && !(InternalObjectKey in children)) {
                children._ctx = currentRenderingInstance;
            }
            else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
                // a child component receives forwarded slots from the parent.
                // its slot type is determined by its parent's slot type.
                if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
                    children._ = 1 /* STABLE */;
                }
                else {
                    children._ = 2 /* DYNAMIC */;
                    vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
                }
            }
        }
    }
    else if (isFunction(children)) {
        children = { default: children, _ctx: currentRenderingInstance };
        type = 32 /* SLOTS_CHILDREN */;
    }
    else {
        children = String(children);
        console.log(children,'children的值')
        // force teleport children to array so it can be moved around
        if (shapeFlag & 64 /* TELEPORT */) {
            type = 16 /* ARRAY_CHILDREN */;
            children = [createTextVNode(children)];
        }
        else {
            type = 8 /* TEXT_CHILDREN */;
        }
    }
    vnode.children = children;
    vnode.shapeFlag |= type;

    console.log(vnode,'最终返回的 vnode值')
}
//传入 type =h1 props =null children ='title' patchFlag = 0, dynamicProps = null, isBlockNode = false ,true
function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
    //相当于constructor构造函数   needFullChildrenNormalization默认值为 false    我们给它传入值为 true
    const vnode = {
        __v_isVNode: true,
        __v_skip: true,
        type,
        props,
        // key: props && normalizeKey(props),   先注释掉
        // ref: props && normalizeRef(props),
        scopeId: currentScopeId,
        slotScopeIds: null,
        children,
        component: null,
        suspense: null,
        ssContent: null,
        ssFallback: null,
        dirs: null,
        transition: null,
        el: null,
        anchor: null,
        target: null,
        targetAnchor: null,
        staticCount: 0,
        shapeFlag,   // 值为1
        patchFlag,
        dynamicProps,
        dynamicChildren: null,
        appContext: null
    };



    console.log(vnode,'被创建的 vnode对象')

    //这里值为true 进入代码块
    if (needFullChildrenNormalization) {
        //传入创建好的 vnode   children 还是之前传入的 'title'
        normalizeChildren(vnode, children);  // #30
        // normalize suspense children


        console.log(shapeFlag & 128,'与操作结果1')
        //这段代码不执行
        if (shapeFlag & 128 /* SUSPENSE */) {
            type.normalize(vnode);
        }
    }
    else if (children) {
        // compiled element vnode - if children is passed, only possible types are
        // string or Array.
        vnode.shapeFlag |= isString(children)
            ? 8 /* TEXT_CHILDREN */
            : 16 /* ARRAY_CHILDREN */;
    }
    // validate key
    if (vnode.key !== vnode.key) {
        warn$1(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
    }
    // track vnode for block tree
    if (isBlockTreeEnabled > 0 &&
        // avoid a block node from tracking itself
        !isBlockNode &&
        // has current parent block
        currentBlock &&
        // presence of a patch flag indicates this node needs patching on updates.
        // component nodes also should always be patched, because even if the
        // component doesn't need to update, it needs to persist the instance on to
        // the next vnode so that it can be properly unmounted later.
        (vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
        // the EVENTS flag is only for hydration and if it is the only flag, the
        // vnode should not be considered dynamic due to handler caching.
        vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
        currentBlock.push(vnode);
    }
    return vnode;
}
function isReactive(value) {
    if (isReadonly(value)) {
        return isReactive(value["__v_raw" /* RAW */]);
    }
    return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
}
function isReadonly(value) {
    return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
}
function isProxy(value) {
    return isReactive(value) || isReadonly(value);
}


function normalizeStyle(value) {
    if (isArray(value)) {
        const res = {};
        for (let i = 0; i < value.length; i++) {
            const item = value[i];
            const normalized = isString(item)
                ? parseStringStyle(item)
                : normalizeStyle(item);
            if (normalized) {
                for (const key in normalized) {
                    res[key] = normalized[key];
                }
            }
        }
        return res;
    }
    else if (isString(value)) {
        return value;
    }
    else if (isObject(value)) {
        return value;
    }
}
//判断传入的props 是否为 proxy拦截 对象
function guardReactiveProps(props) {
    if (!props)
        return null;
    return isProxy(props) || InternalObjectKey in props
        ? extend({}, props)
        : props;
}
function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
    console.log(type,'传入type的值')   //之前使用h() 函数传递 h1
    console.log(props,'传入props的值')  //这里默认值就为null
    console.log(children,'传入children的值')  // 这里为传入的值 'title'
    //判断值为 false 不进入
    // if (!type || type === NULL_DYNAMIC_COMPONENT) {
    //     if (!type) {
    //         warn$1(`Invalid vnode type when creating vnode: ${type}.`);
    //     }
    //     type = Comment$1;
    // }
    console.log(isVNode(type),'判断是否为虚拟节点')
    //判断是否是否是虚拟节点,我们这里传的是h1节点,并不是虚拟节点。所以判断值为false
    //并不会执行这一作用域的代码
    if (isVNode(type)) {
        // createVNode receiving an existing vnode. This happens in cases like
        // <component :is="vnode"/>
        // #2078 make sure to merge refs during the clone instead of overwriting it
        const cloned = cloneVNode(type, props, true /* mergeRef: true */);
        if (children) {
            normalizeChildren(cloned, children);
        }
        return cloned;
    }

    console.log(isClassComponent(type),'判断是否为classComponetn')  //我们传入type 为h1 控制台输出为 false
    // class component normalization.
    if (isClassComponent(type)) {
        type = type.__vccOpts;
    }

    //props 值为null 下面作用域代码并不会执行
    // class & style normalization.
    if (props) {
        // for reactive or proxy objects, we need to clone it to enable mutation.
        props = guardReactiveProps(props);

        console.log(props,'传入值为对象时的props')
        //传入样式属性
        let { class: klass, style } = props;
        if (klass && !isString(klass)) {
            props.class = normalizeClass(klass);
        }
        if (isObject(style)) {
            // reactive state objects need to be cloned since they are likely to be
            // mutated
            if (isProxy(style) && !isArray(style)) {
                style = extend({}, style);
            }
            props.style = normalizeStyle(style);
        }
    }
    // encode the vnode type information into a bitmap

    console.log(isString(type),'判断传入节点是否为string')   //控制台输出为true
    //shapeFlag 值为1
    const shapeFlag = isString(type)
        ? 1 /* ELEMENT */
        : isSuspense(type)
            ? 128 /* SUSPENSE */
            : isTeleport(type)
                ? 64 /* TELEPORT */
                : isObject(type)
                    ? 4 /* STATEFUL_COMPONENT */
                    : isFunction(type)
                        ? 2 /* FUNCTIONAL_COMPONENT */
                        : 0;
    console.log(shapeFlag&4,'与操作结果')   //控制台输出为 0
    if (shapeFlag & 4 /* STATEFUL_COMPONENT */ && isProxy(type)) {
        type = toRaw(type);
        //百度翻译了一下,我们设置的type  为h1 是不会报这个警告
        // Vue接收到一个组件,该组件被设置为反应对象。这个可以导致不必要的性能开销,
        // 应通过以下方式避免使用“markRaw”或“shallowRef”标记组件+而不是“ref”`.`\n使其成为反应性的组件
        warn$1(`Vue received a Component which was made a reactive object. This can ` +
            `lead to unnecessary performance overhead, and should be avoided by ` +
            `marking the component with \`markRaw\` or using \`shallowRef\` ` +
            `instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
    }

    //最终返回的一个被创建的baseNode节点
    //传入 type =h1 props =null children ='title' patchFlag = 0, dynamicProps = null, isBlockNode = false ,true
    return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
}
const createVNodeWithArgsTransform = (...args) => {
    // vnodeArgsTransformer 值为Undefined 所以取的是后半段args的结构
    console.log(...(vnodeArgsTransformer ? vnodeArgsTransformer(args, currentRenderingInstance): args),'args解构后的值')
    return _createVNode(...(vnodeArgsTransformer ? vnodeArgsTransformer(args, currentRenderingInstance): args));
};

const createVNode = (createVNodeWithArgsTransform )

function h(type, propsOrChildren, children) {
    const l = arguments.length;
    console.log(l,'arguments.lenght')
    if (l === 2) {
        if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
            // single vnode without props
            if (isVNode(propsOrChildren)) {
                return createVNode(type, null, [propsOrChildren]);
            }
            // props without children
            return createVNode(type, propsOrChildren);
        }
        else {
            // omit props
            return createVNode(type, null, propsOrChildren);
        }
    }
    else {
        if (l > 3) {
            children = Array.prototype.slice.call(arguments, 2);
        }
        else if (l === 3 && isVNode(children)) {
            children = [children];
        }
        return createVNode(type, propsOrChildren, children);
    }
}


var result = h('h1',{style:{color:'red'}},{title:1})
console.log(result,'最终得到的result')


// const a =(...args)=>{
//     console.log(args)
// }
// const b= (a)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值