Stencil报错‘vNode passed as children has unexpected type’的原因与解决
问题原因
Stencil的JSX渲染系统基于虚拟DOM(vNode)工作,你通过template.content.querySelector("path")获取到的是真实的DOM元素对象,而非Stencil能识别的虚拟节点。直接将真实DOM作为JSX的子节点传入,就会触发"vNode passed as children has unexpected type"错误。
而直接将path字符串写入SVG的innerHTML,是直接操作真实DOM,绕开了Stencil的虚拟DOM校验逻辑,因此可以正常显示。
修复方案
方案一:直接使用innerHTML属性(推荐)
无需手动解析DOM,直接在JSX中给SVG设置innerHTML属性,把path字符串传入即可:
@Prop({ mutable: true }) path: string = '<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5v-5a7 7 0 1 0-14 0v5c-.03 2.47-.72 4.887-2 7h18a13.833 13.833 0 0 1-2-7Z"/>' render() { return ( <svg class="inline-svg" width={this.ifxIcon.width} height={this.ifxIcon.height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" innerHTML={this.path} /> ); }
方案二:将真实DOM转为虚拟节点(复杂场景可选)
如果必须处理DOM元素(比如需要动态修改属性),可以借助Stencil的h函数手动构建虚拟节点:
import { h } from '@stencil/core'; @Prop({ mutable: true }) path: string = '<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5v-5a7 7 0 1 0-14 0v5c-.03 2.47-.72 4.887-2 7h18a13.833 13.833 0 0 1-2-7Z"/>' parsePathToVNode() { const template = document.createElement('template'); template.innerHTML = this.path; const pathEl = template.content.querySelector('path'); if (!pathEl) return null; // 提取path元素的所有属性 const attrs = {}; for (let i = 0; i < pathEl.attributes.length; i++) { const attr = pathEl.attributes[i]; attrs[attr.name] = attr.value; } // 用h函数创建虚拟节点 return h('path', attrs); } render() { return ( <svg class="inline-svg" width={this.ifxIcon.width} height={this.ifxIcon.height} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" > {this.parsePathToVNode()} </svg> ); }
内容的提问来源于stack exchange,提问作者happy_story
相关产品推荐
相关产品推荐

