Lit Element项目挂载Stripe Elements到ShadowRoot报错如何解决
问题根因
Stripe Elements 目前原生不支持直接挂载到 Shadow DOM 节点,其内部的事件绑定、样式注入逻辑仅适配 Light DOM 环境,因此抛出了对应的集成错误。
同时你当前的代码存在两个可优化点:
loadStripe的入参应为Stripe账户公钥,不是支付意图的clientSecret,clientSecret是后续确认支付阶段才需要使用的参数stripe、elements、card变量未声明,建议补充声明避免全局变量污染
可行解决方案
方案1:禁用当前Checkout组件的Shadow DOM
如果你的组件不需要Shadow DOM的样式隔离能力,可以直接覆写Lit的createRenderRoot方法,让组件内容直接渲染到Light DOM中,即可正常挂载Stripe Elements:
import { LitElement, html, css, property, query } from "lit-element"; import { connect } from "pwa-helpers"; import { store } from "../redux/store"; import { loadStripe } from '@stripe/stripe-js'; export class Checkout extends connect(store)(LitElement) { // 新增这段代码禁用Shadow DOM createRenderRoot() { return this; } async init() { const stripe = await loadStripe('你的Stripe公钥'); const elements = stripe.elements(); const card = elements.create('card'); card.mount(this.querySelector('#stripe-payment-form')); } render() { return html` <div id="stripe-payment-form"></div> ` } }
方案2:保留Shadow DOM,通过插槽桥接Light DOM挂载点
如果你需要保留组件的Shadow DOM样式隔离能力,可以用插槽占位+动态创建Light DOM挂载点的方式实现,既满足Stripe的挂载要求,又不破坏组件的隔离特性:
import { LitElement, html, css, property, query } from "lit-element"; import { connect } from "pwa-helpers"; import { store } from "../redux/store"; import { loadStripe } from '@stripe/stripe-js'; export class Checkout extends connect(store)(LitElement) { async firstUpdated() { // 动态创建Light DOM下的挂载容器,分配到对应插槽 const mountContainer = document.createElement('div'); mountContainer.slot = 'stripe-mount'; this.appendChild(mountContainer); // 初始化并挂载Stripe Elements const stripe = await loadStripe('你的Stripe公钥'); const elements = stripe.elements(); const card = elements.create('card'); card.mount(mountContainer); } render() { return html` <!-- 插槽占位,承载Light DOM中的挂载容器 --> <slot name="stripe-mount"></slot> `; } }
挂载后的Stripe组件会正常显示在插槽位置,你也可以正常在组件的Shadow DOM样式中对插槽内容生效。
内容的提问来源于stack exchange,提问作者Kiran Tangellapalli
相关产品推荐
相关产品推荐

