使用shadcn-svelte <Accordion>如何保留<CardNumber>组件状态?
问题描述
在shadcn-svelte的Accordion组件中嵌入svelte-stripe的CardNumber元素时,遇到以下问题:当包含CardNumber的AccordionContent被关闭后,CardNumber的引用会因DOM被移除而丢失,用户再次打开该Accordion项时,CardNumber的输入值会变为null。
相关组件背景:
- shadcn-svelte Accordion(底层依赖bits-ui Accordion)
- svelte-stripe CardNumber
代码示例:
<script lang="ts"> let cardElement: StripeCardNumberElement; </script> <AccordionItem value="card"> <AccordionTrigger>Card</AccordionTrigger> <AccordionContent> <div> <CardNumber on:change={handleCardNumber} bind:element={cardElement} style={stripeStyle} /> </div> </AccordionContent> </AccordionItem>
解决方案
方案1:让AccordionContent保持挂载(最简单)
bits-ui的AccordionContent组件支持keepMounted属性,设置为true后,关闭Accordion时内容不会被从DOM中卸载,仅通过CSS隐藏。这样CardNumber元素的引用和输入状态会被完整保留。
修改代码如下:
<script lang="ts"> let cardElement: StripeCardNumberElement; </script> <AccordionItem value="card"> <AccordionTrigger>Card</AccordionTrigger> <!-- 添加keepMounted属性 --> <AccordionContent keepMounted={true}> <div> <CardNumber on:change={handleCardNumber} bind:element={cardElement} style={stripeStyle} /> </div> </AccordionContent> </AccordionItem>
方案2:手动缓存并恢复输入值
如果不想让AccordionContent始终挂载,可以在CardNumber的change事件中缓存输入状态,当AccordionContent重新挂载时,通过Stripe元素的API恢复值。
注意:严格遵循Stripe的安全规范,不要在客户端存储完整信用卡号,仅缓存Stripe元素的内部状态值用于恢复输入。
代码示例:
<script lang="ts"> let cardElement: StripeCardNumberElement; // 缓存卡号的状态值(仅用于恢复输入,不会存储敏感数据) let cachedCardState: { number?: string } | null = null; function handleCardNumber(e: CustomEvent<StripeCardNumberElementChangeEvent>) { // 当输入完成时缓存状态 if (e.detail.complete && cardElement) { cachedCardState = cardElement.getValue(); } } // 当AccordionContent重新挂载时恢复值 function onContentMount() { if (cardElement && cachedCardState) { cardElement.setValue(cachedCardState); } } </script> <AccordionItem value="card"> <AccordionTrigger>Card</AccordionTrigger> <AccordionContent on:mount={onContentMount}> <div> <CardNumber on:change={handleCardNumber} bind:element={cardElement} style={stripeStyle} /> </div> </AccordionContent> </AccordionItem>
内容的提问来源于stack exchange,提问作者Andrew Johnson
相关产品推荐
相关产品推荐

