HarmonyOS ArkTS 实战:实现一个房贷计算器
HarmonyOS ArkTS 实战:实现一个房贷计算器
项目效果
本文实现的是一个基于 HarmonyOS 和 ArkTS 的房贷计算器。项目中使用 ArkUI 组件完成页面布局,通过@State管理状态数据,实现贷款金额、期限、利率输入,支持等额本息和等额本金两种计算方式,实时计算月供、总还款和总利息,并显示详细的还款信息。
最终运行效果如下:
页面主要包含以下内容:
- 顶部应用标题;
- 贷款类型切换(商业贷款/公积金/组合贷);
- 贷款金额输入;
- 贷款期限选择;
- 年利率输入;
- 还款方式切换(等额本息/等额本金);
- 计算结果卡片;
- 月供、总还款、总利息显示;
- 页面整体采用 ArkUI 声明式布局。
本文重点是演示如何在 HarmonyOS 项目中使用 ArkTS 和 ArkUI 实现一个财务计算类单页面应用。项目代码主要写在entry/src/main/ets/pages/Index.ets文件中,适合作为 HarmonyOS ArkTS 入门到进阶之间的练习案例。
前言
买房是很多人人生中的大事,而房贷计算是买房过程中必不可少的环节。了解月供、总利息等信息可以帮助我们更好地规划财务,选择合适的贷款方案。手动计算房贷公式复杂,容易出错,一个好用的房贷计算器可以快速准确地给出结果。
从应用开发角度来看,这个项目不依赖后端接口,也不需要数据库,但能练习 ArkTS 中的状态管理、表单输入、单选按钮、实时计算、数学公式和结果展示等内容。
本文基于 HarmonyOS 和 ArkTS 实现一个房贷计算器。用户可以输入贷款金额、期限和利率,选择还款方式,实时看到月供、总还款和总利息等关键数据,帮助用户做出购房决策。
这个项目的核心不是简单的数学公式,而是准确的财务计算和清晰的结果展示。每一次参数修改和方式切换,本质上都是对计算状态的管理。状态变化后,页面会自动刷新,这正是 ArkUI 声明式开发的基本思想。
一、项目目标
本次实践主要实现以下目标:
- 创建 HarmonyOS ArkTS 页面;
- 使用
@Entry和@Component定义页面组件; - 使用
@State管理页面状态; - 支持商业贷款计算;
- 支持等额本息还款方式;
- 支持等额本金还款方式;
- 贷款金额输入(万元);
- 贷款期限选择(年);
- 年利率输入(%);
- 实时计算月供;
- 计算总还款额;
- 计算总利息;
- 显示首月/末月月供(等额本金);
- 使用
@Builder封装输入项和结果卡片; - 完成一个可以运行的房贷计算器页面。
这个项目虽然是单页面应用,但它实现了专业的房贷计算功能,有完整的输入、计算和结果展示流程,比普通静态页面更适合练习 ArkTS。
二、技术栈
| 类型 | 内容 |
|---|---|
| 开发方向 | HarmonyOS 应用开发 |
| 开发语言 | ArkTS |
| UI 框架 | ArkUI |
| SDK 版本 | HarmonyOS API 23 及以上 |
| 工程模型 | Stage 模型 |
| 核心组件 | Text / TextInput / Button / Radio / Column / Row |
| 状态管理 | @State |
| 数据处理 | 财务计算 / 数学公式 / 实时响应 |
| 项目入口 | entry/src/main/ets/pages/Index.ets |
| 运行平台 | 模拟器或真机 |
本项目是 HarmonyOS 原生 ArkTS 项目。页面主体由 ArkUI 组件构建,核心逻辑写在Index.ets文件中,不依赖后端接口,也不需要额外配置数据库。
三、为什么选择房贷计算器项目
房贷计算器适合作为 ArkTS 练习项目,主要有以下几个原因。
第一,实用性强。房贷计算是很多人买房时都会用到的功能,有很强的实际需求。
第二,业务场景真实。购房决策需要了解月供压力和利息成本,是非常实用的财务工具。
第三,适合练习状态管理。贷款金额、期限、利率、还款方式都属于页面状态。状态变化后,页面会自动刷新。
第四,适合练习表单交互。数字输入、单选按钮等表单控件的使用是前端开发基础。
第五,适合练习复杂计算。等额本息和等额本金有不同的计算公式,可以锻炼逻辑能力。
第六,扩展空间比较大。基础功能完成后,可以继续增加公积金贷款、组合贷、提前还款计算、还款明细和税费计算。
在本项目中,输入参数和还款方式是核心数据。所有计算结果都基于这些参数实时计算。
四、功能规则说明
还款方式:
| 方式 | 特点 |
|---|---|
| 等额本息 | 每月还款额相同,前期利息多本金少 |
| 等额本金 | 每月本金相同,月供逐月递减,总利息少 |
计算公式:
等额本息:
- 月供 = [贷款本金×月利率×(1+月利率)^还款月数] ÷ [(1+月利率)^还款月数-1]
- 总还款 = 月供 × 还款月数
- 总利息 = 总还款 - 贷款本金
等额本金:
- 首月月供 = (贷款本金÷还款月数) + (贷款本金-已还本金)×月利率
- 每月递减 = 贷款本金÷还款月数×月利率
- 总利息 = (还款月数+1)×贷款本金×月利率÷2
- 总还款 = 贷款本金 + 总利息
默认参数:
- 贷款金额:100万元
- 贷款期限:30年
- 年利率:4.9%(商业贷款基准利率)
- 还款方式:等额本息
五、项目结构
本项目主要修改首页文件:
entry └── src └── main └── ets └── pages └── Index.ets其中:
| 文件 | 作用 |
|---|---|
| Index.ets | 编写页面结构、状态数据和房贷计算逻辑 |
本文不涉及复杂路由,也不需要额外创建多个页面。对于练习项目来说,把主要逻辑集中在一个Index.ets文件中更方便理解。
六、核心实现思路
本项目的核心流程如下:
- 使用
@State保存贷款金额、期限、年利率和还款方式; - 用户输入贷款金额(万元);
- 用户选择贷款期限;
- 用户输入年利率;
- 用户选择还款方式;
- 参数变化时自动重新计算;
- 根据还款方式使用对应公式计算;
- 显示月供、总还款、总利息等结果;
- 等额本金时显示首月和末月月供;
- 格式化金额显示,添加千分位分隔符。
项目中最重要的状态变量如下:
@State loanAmount: string = '100' @State loanYears: number = 30 @State interestRate: string = '4.9' @State repaymentType: number = 0其中:
| 状态变量 | 作用 |
|---|---|
| loanAmount | 贷款金额(万元) |
| loanYears | 贷款期限(年) |
| interestRate | 年利率(%) |
| repaymentType | 还款方式(0=等额本息,1=等额本金) |
这些参数是计算的基础,任何一个变化都会触发重新计算。
七、Index.ets 完整代码
打开文件:
entry/src/main/ets/pages/Index.ets将其中内容替换为下面代码:
@Entry@Componentstruct Index{@StateloanAmount:string='100'@StateloanYears:number=30@StateinterestRate:string='4.9'@StaterepaymentType:number=0privateyearOptions:number[]=[5,10,15,20,25,30]privategetMonthlyPayment():number{letprincipal=this.getPrincipal()letmonths=this.loanYears*12letmonthlyRate=this.getMonthlyRate()if(principal<=0||monthlyRate<=0||months<=0)return0if(this.repaymentType===0){returnprincipal*monthlyRate*Math.pow(1+monthlyRate,months)/(Math.pow(1+monthlyRate,months)-1)}else{returnprincipal/months+principal*monthlyRate}}privategetLastMonthlyPayment():number{if(this.repaymentType===0)returnthis.getMonthlyPayment()letprincipal=this.getPrincipal()letmonths=this.loanYears*12letmonthlyRate=this.getMonthlyRate()letmonthlyPrincipal=principal/monthsreturnmonthlyPrincipal+monthlyPrincipal*monthlyRate}privategetTotalPayment():number{letprincipal=this.getPrincipal()letmonths=this.loanYears*12letmonthlyRate=this.getMonthlyRate()if(this.repaymentType===0){returnthis.getMonthlyPayment()*months}else{returnprincipal+(months+1)*principal*monthlyRate/2}}privategetTotalInterest():number{returnthis.getTotalPayment()-this.getPrincipal()}privategetPrincipal():number{letamount=parseFloat(this.loanAmount)returnisNaN(amount)?0:amount*10000}privategetMonthlyRate():number{letrate=parseFloat(this.interestRate)returnisNaN(rate)?0:rate/100/12}privateformatMoney(amount:number):string{returnamount.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g,',')}@BuilderInputItem(label:string,value:string,unit:string,onChange:(v:string)=>void,placeholder?:string){Row(){Text(label).fontSize(15).fontColor('#182431').width(90)TextInput({text:value,placeholder:placeholder||''}).layoutWeight(1).height(44).fontSize(16).textAlign(TextAlign.End).backgroundColor(Color.Transparent).type(InputType.Number).onChange(onChange)Text(unit).fontSize(15).fontColor('#6B7280').margin({left:8})}.width('100%').padding({left:16,right:16}).height(56).backgroundColor('#F9FAFB').borderRadius(12).margin({bottom:12})}@BuilderResultItem(label:string,value:string,highlight:boolean=false){Row(){Text(label).fontSize(14).fontColor('#6B7280')Blank()Text(value).fontSize(highlight?24:18).fontWeight(highlight?FontWeight.Bold:FontWeight.Medium).fontColor(highlight?'#0A59F7':'#182431')}.width('100%').padding({top:12,bottom:12})}build(){Column(){Text('房贷计算器').fontSize(28).fontWeight(FontWeight.Bold).fontColor('#182431').margin({top:22})Text('基于 HarmonyOS ArkTS 的房贷计算工具').fontSize(14).fontColor('#6B7280').margin({top:8,bottom:20})Column(){Text('贷款信息').fontSize(16).fontWeight(FontWeight.Medium).fontColor('#182431').width('100%').margin({bottom:12})this.InputItem('贷款金额',this.loanAmount,'万元',(v:string)=>{this.loanAmount=v},'请输入金额')Text('贷款期限').fontSize(15).fontColor('#182431').width('100%').margin({bottom:8})Flex({wrap:FlexWrap.Wrap,justifyContent:FlexAlign.Start}){ForEach(this.yearOptions,(year:number)=>{Button(`${year}年`).height(36).padding({left:16,right:16}).fontSize(14).margin({right:8,bottom:8}).fontColor(this.loanYears===year?Color.White:'#4B5563').backgroundColor(this.loanYears===year?'#0A59F7':'#F3F4F6').borderRadius(18).onClick(()=>{this.loanYears=year})},(y:number)=>y.toString())}.width('100%').margin({bottom:12})this.InputItem('年利率',this.interestRate,'%',(v:string)=>{this.interestRate=v},'请输入利率')Text('还款方式').fontSize(15).fontColor('#182431').width('100%').margin({bottom:8})Row(){Row(){Radio({value:'0',group:'repayType'}).checked(this.repaymentType===0).onChange((isChecked:boolean)=>{if(isChecked)this.repaymentType=0})Text('等额本息').fontSize(15).fontColor('#182431').margin({left:8})}.onClick(()=>{this.repaymentType=0})Blank().width(40)Row(){Radio({value:'1',group:'repayType'}).checked(this.repaymentType===1).onChange((isChecked:boolean)=>{if(isChecked)this.repaymentType=1})Text('等额本金').fontSize(15).fontColor('#182431').margin({left:8})}.onClick(()=>{this.repaymentType=1})}.width('100%')}.width('100%').padding(16).backgroundColor(Color.White).borderRadius(16).margin({bottom:16}).shadow({radius:8,color:'#08000000',offsetX:0,offsetY:2})Column(){Text('计算结果').fontSize(16).fontWeight(FontWeight.Medium).fontColor('#182431').width('100%').margin({bottom:8})this.ResultItem(this.repaymentType===0?'每月月供':'首月月供',`${this.formatMoney(this.getMonthlyPayment())}元`,true)if(this.repaymentType===1){this.ResultItem('末月月供',`${this.formatMoney(this.getLastMonthlyPayment())}元`)Divider().color('#F3F4F6')}this.ResultItem('还款总额',`${this.formatMoney(this.getTotalPayment())}元`)Divider().color('#F3F4F6')this.ResultItem('支付利息',`${this.formatMoney(this.getTotalInterest())}元`)}.width('100%').padding(20).backgroundColor(Color.White).borderRadius(16).shadow({radius:8,color:'#08000000',offsetX:0,offsetY:2})Text('* 计算结果仅供参考,实际以银行审批为准').fontSize(12).fontColor('#9CA3AF').margin({top:16})}.width('100%').height('100%').padding({left:18,right:18}).backgroundColor('#F5F7FA')}}八、代码实现说明
1. 等额本息计算
使用等额本息公式计算每月还款额:
returnprincipal*monthlyRate*Math.pow(1+monthlyRate,months)/(Math.pow(1+monthlyRate,months)-1)总还款 = 月供 × 月数,总利息 = 总还款 - 本金。
2. 等额本金计算
等额本金首月月供最高,逐月递减:
// 首月月供 = 月还本金 + 全额本金月利息returnprincipal/months+principal*monthlyRate// 末月月供 = 月还本金 + 剩余1个月本金利息returnmonthlyPrincipal+monthlyPrincipal*monthlyRate总利息使用等差数列求和公式计算。
3. 实时计算
参数变化时自动重新计算,不需要点击计算按钮,提供流畅体验。
4. 金额格式化
使用正则表达式添加千分位分隔符,让大额数字更易读:
returnamount.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g,',')5. 期限快捷选择
提供常用贷款期限的快捷按钮,点击即可选择,比输入更方便。
6. 还款方式切换
使用Radio组件选择还款方式,切换后自动重新计算,等额本金时额外显示末月月供。
九、运行项目
代码编写完成后,在DevEco Studio中运行项目。测试不同金额、期限、利率和还款方式的计算结果,验证公式正确性,检查结果格式化是否正确。
十、开发中遇到的问题
- 财务公式准确性:确保等额本息和等额本金公式正确
- 边界情况处理:输入0或非法值时返回0,避免NaN
- 金额格式化:正确添加千分位分隔符,保留两位小数
- 等额本金特殊显示:需要显示首月和末月月供,因为每月递减
十一、总结
本文基于HarmonyOS和ArkTS实现了一个房贷计算器。项目通过@State管理输入参数,使用专业的财务公式实现等额本息和等额本金计算,实时显示月供、总还款和总利息。这个项目展示了ArkTS中表单输入、实时计算和数学公式应用的基本方法,适合作为入门练习项目。