domItem. innerHTML = ' <div>现在是innerHTML</div>' ; } else { domItem. innerText = '<div>现在是innerText</div>' ; console . log (domItem); return h ( 'span' , {}, [ h ( 'div' , { innerText : 'Vue的h函数切换渲染innerHTML和innerText异常:' }), h ( 'span' , domItem), h ( 'button' , { onClick : this . change , innerText : '切换' , </script> < style scoped > div { margin : 10px ; span { margin-right : 20px ; </ style >

测试结果发现:

  • 进入页面后正常渲染innerHTML如下
  •  const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
     // oldProps = {innerHTML: " <div>现在是innerHTML</div>"}
     // newProps = {innerText: "<div>现在是innerText</div>" }
            if (oldProps !== newProps) {
                // 先遍历newProps
                for (const key in newProps) {
                    // 此时遍历的key为innerText
                    // empty string is not valid prop
                    if (isReservedProp(key))
                        continue;
                    const next = newProps[key];
                    // next = "<div>现在是innerText</div>"
                    const prev = oldProps[key];
                    // prev = "";
                    // defer patching value
                    if (next !== prev && key !== 'value') {
                        hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
                        // 到此处时会渲染出 <div>现在是innerText</div>
                if (oldProps !== EMPTY_OBJ) {
                // 再遍历oldProps
                    for (const key in oldProps) {
                        // 此时的key为innerHTML
                        if (!isReservedProp(key) && !(key in newProps)) {
                            hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
                            // 此处会渲染innerHTML,而newProps的innerHTML为空,故最终渲染为空
    

    总结: Vue在最终渲染时,会先遍历新的newProps对象,将新的newProps中属性值都渲染出来;再遍历旧的oldProps对象,将旧的oldProps[key] = newProps[key],上例中,遍历newProps时,将innerText渲染为<div>现在是innerText</div>,遍历oldProps时,将innerHTML渲染为空。 所以最终变成了渲染成了空。

    目前我的解决方式是,都用innerHTML渲染好了。不知道读者朋友们有什么更好的方案吗?

    给官方提了一个BUG:Vue's H function switches rendering innerHTML and innerText exceptions. · Issue #6571 · vuejs/core (github.com)

  •