分期付款試算(React)
商品頁內嵌的分期試算 React 元件:3/6/12/24 期 segmented 切換、年利率與手續費、每期金額逐位滾動、總金額與利息、實質年利率、0 利率徽章與可展開的逐期明細表。
台灣電商商品頁常見的「最低每期 NT$XXX」。傳入商品金額與方案清單(期數、年利率、手續費),元件用等額本息公式算出每期金額,並以逐位滾動數字呈現;切換期數時選中膠囊滑過去、總金額/利息+手續費/實質年利率同步更新,零利率方案自動掛上「0 利率」徽章。需要的話再展開逐期明細,看每一期的本金、利息與剩餘本金。計算函式 computeInstallment 另行匯出,商品列表要顯示「最低每期」時可直接呼叫。
載入預覽⋯
npx shadcn@latest add https://webberui.com/r/installment-calculator.jsonPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
36900
3000
<InstallmentCalculator />
安裝
npx shadcn@latest add https://webberui.com/r/installment-calculator.json或在 components.json 設定 registries 後,改用 @webberui/installment-calculator 安裝。
使用
import {
InstallmentCalculator,
computeInstallment,
} from "@/components/ui/installment-calculator";
<InstallmentCalculator
price={36900}
plans={[
{ months: 3, annualRate: 0 },
{ months: 6, annualRate: 0, badge: "熱門" },
{ months: 12, annualRate: 4.99 },
{ months: 24, annualRate: 7.99, fee: 300 },
]}
defaultMonths={6}
minAmount={3000}
onChange={(plan, result) =>
console.log(`${plan.months} 期,每期 NT$${result.monthly}`)
}
/>
// 計算函式可單獨使用(例如商品列表顯示「最低每期」)
const { monthly, effectiveAnnualRate } = computeInstallment(36900, 12, 4.99);Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
price | number | — | 商品金額(元) |
plans | InstallmentPlan[] | 3/6/12/24 期 | 分期方案清單;預設 3/6 期零利率、12 期 4.5%、24 期 6.5% |
value | number | — | 受控:目前選中的期數(需存在於 plans) |
defaultMonths | number | 第一個方案 | 非受控:初始選中的期數;不在 plans 內時取第一個方案 |
onChange | (plan: InstallmentPlan, result: InstallmentResult) => void | — | 使用者切換期數時回呼,帶回選中的方案與該方案的試算結果 |
currency | string | "NT$" | 貨幣前綴 |
showSchedule | boolean | true | 是否提供可展開的逐期明細表 |
minAmount | number | 0 | 分期最低金額門檻;price 低於此值時改顯示提示、停用方案切換 |
disclaimer | string | "實際費率以發卡銀行為準" | 底部免責小字;傳空字串可隱藏 |
className | string | — | 透傳到最外層容器 |
InstallmentPlan
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
months | number | — | 期數(月) |
annualRate | number | — | 年利率(%),0 代表零利率 |
fee | number | 0 | 一次性手續費(元) |
label | string | "N 期" | 分段按鈕文字 |
badge | string | — | 分段按鈕右上角的小徽章文字,例如「熱門」 |
InstallmentResult
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
months | number | — | 期數 |
annualRate | number | — | 年利率(%) |
fee | number | — | 手續費(元) |
monthly | number | — | 每期金額(四捨五入到元;末期可能因吸收差額而略有不同) |
total | number | — | 總付款金額(各期金額加總+手續費) |
interest | number | — | 總利息 |
extraCost | number | — | 利息+手續費 |
effectiveAnnualRate | number | — | 實質年利率(%,含手續費,保留兩位小數) |
zeroInterest | boolean | — | 是否為零利率方案 |
schedule | InstallmentScheduleRow[] | — | 逐期明細 |
InstallmentScheduleRow
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
period | number | — | 第幾期(從 1 起算) |
payment | number | — | 本期應付金額(本金+利息) |
principal | number | — | 本期償還本金 |
interest | number | — | 本期利息 |
balance | number | — | 本期繳完後的剩餘本金 |
另外具名匯出 computeInstallment(price, months, annualRate, fee?),回傳 InstallmentResult,方便在商品列表、購物車或結帳頁重複使用同一套算法。
細節
- 公式:月利率
r = annualRate / 12 / 100;r為 0 時每期金額= price / n,否則採等額本息price × r × (1 + r)^n / ((1 + r)^n − 1)。金額四捨五入到元。 - 逐期明細:每期利息
= 剩餘本金 × r、本金= 每期金額 − 利息;末期直接清償剩餘本金,吸收四捨五入的差額,因此各期本金加總恰好等於商品金額。 - 實質年利率:把手續費視為借款當下就付出的成本(淨融資額
= price − fee),以二分法反推每月內部報酬率再乘以 12——手續費為 0 時會等於名目年利率;零利率但有手續費的方案會顯示大於 0 的實質年利率,讓「0 利率」徽章不至於誤導。 - 滾動數字:每一位數字是 0–9 縱向堆疊的滾輪,
translateY到目標值;key 從右邊數起,位數增減時個位永遠是同一個滾輪,新位從左側淡入。首次渲染直接輸出目標位置,hydration 不會從 0 滾一次。 - 門檻:
price低於minAmount時,結果卡換成「未達分期門檻」提示,方案切換停用。
可及性
- 期數切換採
role="radiogroup"+role="radio"/aria-checked,Tab 只停在選中項,方向鍵、Home/End 在方案間移動並選取,焦點以focus-visiblering 顯示 - 每期金額的滾輪層以
aria-hidden隱藏,外層aria-label提供完整金額;另有一句aria-live="polite"的隱藏摘要(期數、每期金額、總金額)在切換時朗讀,不把整張結果卡當 live region 以免過吵 - 明細切換按鈕帶
aria-expanded/aria-controls;明細為原生table,含caption與scope標記的欄/列標題 - 使用者系統開啟「減少動態效果」時,滾輪改為靜態數字,膠囊滑動、徽章彈出、明細展開與數值切換皆改為即時定位,僅保留顏色與文字回饋