当前位置: 首页 > web >正文

从零到一:现代化充电桩App的React前端参考

在新能源汽车蓬勃发展的今天,充电桩App已成为连接车主与充电设施的关键纽带。本文将详细解析如何使用React技术栈构建一款功能完善、用户体验优秀的充电桩管理应用。

项目背景与需求分析

随着电动汽车保有量的快速增长,充电桩的智能化管理需求日益迫切。传统的充电方式存在诸多痛点:

  • 找桩难:用户难以快速找到附近可用的充电桩
  • 排队长:无法预知充电桩使用状况
  • 支付复杂:多种支付方式缺乏统一管理
  • 体验差:缺乏实时充电状态监控

基于这些痛点,我们设计了一款集成化的充电桩管理App,旨在为用户提供一站式的充电服务体验。

技术架构设计

前端技术选型

我们选择了现代化的前端技术栈:

  • React 18:构建用户界面的核心框架
  • Lucide React:提供一致的图标设计语言
  • Tailwind CSS:实现响应式和现代化的UI设计
  • JavaScript ES6+:使用最新的语言特性

核心功能模块

应用采用模块化设计,主要包含以下核心功能:

// 主要功能模块划分
const modules = {home: '首页概览',map: '地图找桩', station: '充电桩详情',charging: '实时充电',history: '充电记录',profile: '个人中心'
};

关键功能实现详解

1. 智能首页设计

首页作为用户的第一接触点,我们精心设计了信息层级:

// 用户状态管理
const [user, setUser] = useState({name: '张先生',balance: 156.80,points: 1250
});// 首页核心信息展示
const HomeView = () => (<div className="space-y-6">{/* 用户信息卡片 - 渐变背景提升视觉效果 */}<div className="bg-gradient-to-r from-blue-600 to-blue-800 text-white p-6 rounded-2xl"><div className="flex items-center justify-between"><div><h2 className="text-xl font-bold">欢迎回来,{user.name}</h2><p className="text-blue-100 mt-1">账户余额:¥{user.balance}</p></div>{/* 积分和钱包信息 */}</div></div>{/* ... */}</div>
);

设计亮点

  • 采用渐变背景提升视觉层次
  • 卡片式布局提供清晰的信息分组
  • 快速操作按钮便于用户直接访问核心功能

2. 智能地图找桩功能

地图模块是整个应用的核心,我们实现了完整的搜索和筛选体系:

// 充电桩数据结构设计
const chargingStations = [{id: 1,name: '万达广场充电站',address: '北京市朝阳区建国路93号万达广场B1层',distance: '0.8km',availablePorts: 3,totalPorts: 8,price: '1.2元/度',rating: 4.8,fastCharging: true,brands: ['特斯拉', '蔚来', '小鹏'],coordinates: { lat: 39.9042, lng: 116.4074 }}// ...更多充电桩数据
];// 搜索功能实现
const MapView = () => (<div className="space-y-4">{/* 智能搜索栏 */}<div className="relative"><Search className="absolute left-3 top-3 w-5 h-5 text-gray-400" /><inputtype="text"placeholder="搜索充电桩、地址或品牌"className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:border-blue-500"value={searchTerm}onChange={(e) => setSearchTerm(e.target.value)}/></div>{/* ... */}</div>
);

技术特色

  • 实时搜索与筛选功能
  • 多维度信息展示(距离、价格、评分、可用性)
  • 响应式列表设计适配不同屏幕尺寸

3. 实时充电监控系统

充电监控是用户最关心的功能,我们实现了完整的实时数据更新机制:

// 充电会话状态管理
const [chargingSession, setChargingSession] = useState(null);// 充电过程实时更新
const ChargingView = () => {const [currentTime, setCurrentTime] = useState(0);const [currentEnergy, setCurrentEnergy] = useState(0);const [currentCost, setCurrentCost] = useState(0);useEffect(() => {if (chargingSession) {const interval = setInterval(() => {setCurrentTime(prev => prev + 1);setCurrentEnergy(prev => prev + 0.5);setCurrentCost(prev => Math.round((prev + 0.6) * 100) / 100);}, 1000);return () => clearInterval(interval);}}, [chargingSession]);// 时间格式化工具函数const formatTime = (seconds) => {const mins = Math.floor(seconds / 60);const secs = seconds % 60;return `${mins}:${secs.toString().padStart(2, '0')}`;};return (<div className="space-y-6">{/* 充电状态指示器 */}<div className="bg-gradient-to-r from-green-500 to-green-600 text-white p-6 rounded-2xl text-center"><div className="w-20 h-20 bg-white/20 rounded-full flex items-center justify-center mx-auto mb-4"><Battery className="w-10 h-10" /></div><h2 className="text-xl font-bold mb-2">正在充电中</h2></div>{/* 实时数据展示 */}</div>);
};

实现亮点

  • 使用useEffectsetInterval实现实时数据更新
  • 视觉化的充电进度条和电池图标
  • 多维度数据展示(时长、电量、费用)

4. 状态管理与用户体验

我们采用React Hooks进行状态管理,确保应用的响应性和数据一致性:

// 全局状态管理
const [currentView, setCurrentView] = useState('home');
const [selectedStation, setSelectedStation] = useState(null);
const [searchTerm, setSearchTerm] = useState('');// 充电流程控制
const startCharging = (station) => {setChargingSession({station: station,startTime: new Date(),currentEnergy: 0,estimatedTime: 45,cost: 0});setCurrentView('charging');
};const stopCharging = () => {if (chargingSession) {// 计算充电结果const duration = Math.floor((new Date() - chargingSession.startTime) / 1000 / 60);const energy = Math.round(duration * 0.8 * 10) / 10;const cost = Math.round(energy * 1.2 * 100) / 100;setChargingSession(null);setCurrentView('complete');}
};

UI/UX设计理念

1. 移动优先的响应式设计

// 移动端优化的容器设计
<div className="max-w-md mx-auto bg-gray-50 min-h-screen">{/* 应用内容 */}
</div>

2. 现代化的视觉设计

  • 渐变色彩:使用CSS渐变创造视觉层次
  • 圆角设计:大量使用rounded-xlrounded-2xl提升现代感
  • 阴影效果:通过边框和背景色变化营造层次感

3. 直观的交互设计

// 底部导航栏实现
<div className="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-md bg-white border-t border-gray-200"><div className="flex justify-around py-2">{[{ icon: Home, label: '首页', view: 'home' },{ icon: MapPin, label: '找桩', view: 'map' },{ icon: History, label: '记录', view: 'history' },{ icon: User, label: '我的', view: 'profile' }].map((item, index) => (<buttonkey={index}onClick={() => setCurrentView(item.view)}className={`flex flex-col items-center py-2 px-4 ${currentView === item.view ? 'text-blue-600' : 'text-gray-500'}`}><item.icon className="w-6 h-6 mb-1" /><span className="text-xs">{item.label}</span></button>))}</div>
</div>

性能优化策略

1. 组件化设计

将不同功能模块拆分为独立组件,便于维护和性能优化:

// 模块化视图组件
const renderCurrentView = () => {switch (currentView) {case 'home': return <HomeView />;case 'map': return <MapView />;case 'station': return <StationView />;case 'charging': return <ChargingView />;case 'complete': return <CompleteView />;case 'history': return <HistoryView />;case 'profile': return <ProfileView />;default: return <HomeView />;}
};

2. 状态更新优化

使用函数式更新避免不必要的重渲染:

// 优化的状态更新
setCurrentTime(prev => prev + 1);
setCurrentEnergy(prev => prev + 0.5);
setCurrentCost(prev => Math.round((prev + 0.6) * 100) / 100);

扩展性设计

1. 数据接口预留

虽然当前使用模拟数据,但数据结构设计考虑了真实API的对接需求:

// 预留API接口结构
const chargingStations = [{id: 1, // 充电桩唯一标识name: '万达广场充电站', // 充电站名称address: '具体地址', // 详细地址coordinates: { lat: 39.9042, lng: 116.4074 }, // GPS坐标availablePorts: 3, // 可用充电桩数量totalPorts: 8, // 总充电桩数量price: '1.2元/度', // 充电价格rating: 4.8, // 用户评分fastCharging: true, // 是否支持快充brands: ['特斯拉', '蔚来', '小鹏'] // 支持的车型品牌}
];

2. 功能模块扩展

架构设计支持轻松添加新功能:

  • 预约充电功能
  • 充电桩故障报修
  • 社交评价系统
  • 积分商城
  • 充电统计报表

部署与优化建议

1. 生产环境优化

  • 启用代码分割和懒加载
  • 图片资源压缩和CDN部署
  • 启用Service Worker离线缓存

2. 真实环境集成

// 地图API集成示例
const initMap = () => {// 集成高德地图或百度地图APIconst map = new AMap.Map('mapContainer', {zoom: 15,center: [116.397428, 39.90923]});
};// 支付接口集成
const processPayment = async (amount) => {// 集成支付宝、微信支付等const result = await paymentAPI.createOrder({amount,description: '充电费用'});return result;
};

项目总结与展望

这款充电桩App展示了现代移动应用开发的最佳实践:

技术亮点

  • React Hooks的深度应用
  • 组件化和模块化设计
  • 响应式UI设计
  • 实时状态管理

用户体验

  • 直观的操作流程
  • 实时数据反馈
  • 现代化视觉设计
  • 完整的功能闭环

商业价值

  • 解决用户找桩难题
  • 提供充电全程管控
  • 构建用户粘性和忠诚度
  • 为充电桩运营提供数据支撑

随着新能源汽车市场的持续扩大,充电桩App作为重要的基础设施入口,将在推动行业数字化转型中发挥越来越重要的作用。本项目为相关开发者提供了完整的技术实现参考,期待能够推动整个行业的技术进步。


界面:

源码

import React, { useState, useEffect } from 'react';
import { MapPin, Battery, CreditCard, User, Search, Navigation,Zap,Clock,Star,Phone,Filter,ChevronRight,Car,Wallet,History,Settings,Home,Play,Square,CheckCircle
} from 'lucide-react';const ChargingStationApp = () => {const [currentView, setCurrentView] = useState('home');const [searchTerm, setSearchTerm] = useState('');const [selectedStation, setSelectedStation] = useState(null);const [chargingSession, setChargingSession] = useState(null);const [user, setUser] = useState({name: '张先生',balance: 156.80,points: 1250});// 模拟充电桩数据const chargingStations = [{id: 1,name: '万达广场充电站',address: '北京市朝阳区建国路93号万达广场B1层',distance: '0.8km',availablePorts: 3,totalPorts: 8,price: '1.2元/度',rating: 4.8,fastCharging: true,brands: ['特斯拉', '蔚来', '小鹏'],coordinates: { lat: 39.9042, lng: 116.4074 }},{id: 2,name: '国贸充电中心',address: '北京市朝阳区国贸桥东南角地下停车场',distance: '1.2km',availablePorts: 1,totalPorts: 6,price: '1.5元/度',rating: 4.6,fastCharging: true,brands: ['比亚迪', '理想', '华为'],coordinates: { lat: 39.9088, lng: 116.4317 }},{id: 3,name: 'CBD商务区充电站',address: '北京市朝阳区光华路SOHO现代城停车场',distance: '2.1km',availablePorts: 5,totalPorts: 10,price: '1.0元/度',rating: 4.9,fastCharging: false,brands: ['通用充电'],coordinates: { lat: 39.9127, lng: 116.4194 }}];const chargingHistory = [{id: 1,station: '万达广场充电站',date: '2025-08-24',duration: '45分钟',energy: '28.5度',cost: '34.2元',status: '已完成'},{id: 2,station: '国贸充电中心',date: '2025-08-22',duration: '1小时20分',energy: '42.8度',cost: '64.2元',status: '已完成'}];const startCharging = (station) => {setChargingSession({station: station,startTime: new Date(),currentEnergy: 0,estimatedTime: 45,cost: 0});setCurrentView('charging');};const stopCharging = () => {if (chargingSession) {const duration = Math.floor((new Date() - chargingSession.startTime) / 1000 / 60);const energy = Math.round(duration * 0.8 * 10) / 10;const cost = Math.round(energy * 1.2 * 100) / 100;// 添加到历史记录setChargingSession(null);setCurrentView('complete');}};// 首页视图const HomeView = () => (<div className="space-y-6">{/* 用户信息卡片 */}<div className="bg-gradient-to-r from-blue-600 to-blue-800 text-white p-6 rounded-2xl"><div className="flex items-center justify-between"><div><h2 className="text-xl font-bold">欢迎回来,{user.name}</h2><p className="text-blue-100 mt-1">账户余额:¥{user.balance}</p></div><div className="text-right"><div className="bg-white/20 rounded-lg p-2"><Wallet className="w-8 h-8" /></div><p className="text-sm text-blue-100 mt-1">{user.points} 积分</p></div></div></div>{/* 快速操作 */}<div className="grid grid-cols-2 gap-4"><button onClick={() => setCurrentView('map')}className="bg-green-50 p-4 rounded-xl border border-green-200 hover:bg-green-100 transition-colors"><MapPin className="w-8 h-8 text-green-600 mb-2" /><p className="font-semibold text-green-800">查找充电桩</p><p className="text-sm text-green-600">附近3个可用</p></button><button onClick={() => setCurrentView('history')}className="bg-purple-50 p-4 rounded-xl border border-purple-200 hover:bg-purple-100 transition-colors"><History className="w-8 h-8 text-purple-600 mb-2" /><p className="font-semibold text-purple-800">充电记录</p><p className="text-sm text-purple-600">查看历史</p></button></div>{/* 附近充电桩 */}<div><h3 className="font-bold text-lg mb-4">附近充电桩</h3><div className="space-y-3">{chargingStations.slice(0, 2).map(station => (<div key={station.id} className="bg-white p-4 rounded-xl border border-gray-200 hover:border-blue-300 transition-colors cursor-pointer"onClick={() => {setSelectedStation(station); setCurrentView('station');}}><div className="flex justify-between items-start mb-2"><h4 className="font-semibold text-gray-800">{station.name}</h4><span className="text-sm text-gray-500">{station.distance}</span></div><p className="text-sm text-gray-600 mb-3">{station.address}</p><div className="flex justify-between items-center"><div className="flex items-center space-x-4"><span className="text-sm text-green-600">● {station.availablePorts}/{station.totalPorts} 可用</span><span className="text-sm text-blue-600">{station.price}</span></div><div className="flex items-center"><Star className="w-4 h-4 text-yellow-400 mr-1" /><span className="text-sm text-gray-600">{station.rating}</span></div></div></div>))}</div></div></div>);// 地图视图const MapView = () => (<div className="space-y-4">{/* 搜索栏 */}<div className="relative"><Search className="absolute left-3 top-3 w-5 h-5 text-gray-400" /><inputtype="text"placeholder="搜索充电桩、地址或品牌"className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:border-blue-500"value={searchTerm}onChange={(e) => setSearchTerm(e.target.value)}/><Filter className="absolute right-3 top-3 w-5 h-5 text-gray-400" /></div>{/* 地图区域 */}<div className="bg-gray-100 rounded-xl h-64 flex items-center justify-center border border-gray-200"><div className="text-center"><MapPin className="w-12 h-12 text-blue-600 mx-auto mb-2" /><p className="text-gray-600">地图加载中...</p><p className="text-sm text-gray-500 mt-1">显示附近充电桩位置</p></div></div>{/* 筛选条件 */}<div className="flex space-x-2 overflow-x-auto pb-2">{['全部', '快充', '慢充', '特斯拉', '蔚来', '小鹏'].map(filter => (<button key={filter} className="px-4 py-2 bg-gray-100 rounded-full text-sm whitespace-nowrap hover:bg-blue-100 hover:text-blue-600">{filter}</button>))}</div>{/* 充电桩列表 */}<div className="space-y-3">{chargingStations.map(station => (<div key={station.id} className="bg-white p-4 rounded-xl border border-gray-200 hover:border-blue-300 transition-colors cursor-pointer"onClick={() => {setSelectedStation(station); setCurrentView('station');}}><div className="flex justify-between items-start mb-2"><div><h4 className="font-semibold text-gray-800">{station.name}</h4><div className="flex items-center mt-1"><Navigation className="w-4 h-4 text-gray-400 mr-1" /><span className="text-sm text-gray-500">{station.distance}</span></div></div><div className="text-right"><span className={`text-sm font-medium ${station.availablePorts > 0 ? 'text-green-600' : 'text-red-600'}`}>{station.availablePorts > 0 ? '有空位' : '已满'}</span><div className="flex items-center mt-1"><Star className="w-4 h-4 text-yellow-400 mr-1" /><span className="text-sm text-gray-600">{station.rating}</span></div></div></div><p className="text-sm text-gray-600 mb-3">{station.address}</p><div className="flex justify-between items-center"><div className="flex items-center space-x-4"><span className="text-sm text-blue-600">{station.price}</span><span className="text-sm text-gray-500">{station.availablePorts}/{station.totalPorts} 可用</span>{station.fastCharging && (<span className="bg-orange-100 text-orange-600 px-2 py-1 rounded text-xs">快充</span>)}</div><ChevronRight className="w-5 h-5 text-gray-400" /></div></div>))}</div></div>);// 充电桩详情视图const StationView = () => {if (!selectedStation) return null;return (<div className="space-y-6">{/* 基本信息 */}<div className="bg-white p-6 rounded-2xl border border-gray-200"><h2 className="text-xl font-bold text-gray-800 mb-2">{selectedStation.name}</h2><p className="text-gray-600 mb-4">{selectedStation.address}</p><div className="grid grid-cols-2 gap-4 mb-6"><div className="text-center p-4 bg-green-50 rounded-xl"><div className="text-2xl font-bold text-green-600">{selectedStation.availablePorts}</div><div className="text-sm text-green-600">可用充电位</div></div><div className="text-center p-4 bg-blue-50 rounded-xl"><div className="text-2xl font-bold text-blue-600">{selectedStation.price}</div><div className="text-sm text-blue-600">充电价格</div></div></div><div className="flex items-center justify-between mb-4"><div className="flex items-center"><Star className="w-5 h-5 text-yellow-400 mr-1" /><span className="font-medium">{selectedStation.rating}</span><span className="text-gray-500 text-sm ml-2">(128条评价)</span></div><div className="flex items-center text-gray-600"><Navigation className="w-4 h-4 mr-1" /><span className="text-sm">{selectedStation.distance}</span></div></div><div className="border-t pt-4"><h3 className="font-medium mb-3">支持充电接口</h3><div className="flex flex-wrap gap-2">{selectedStation.brands.map(brand => (<span key={brand} className="bg-gray-100 text-gray-700 px-3 py-1 rounded-full text-sm">{brand}</span>))}</div></div></div>{/* 操作按钮 */}<div className="grid grid-cols-2 gap-4"><button className="bg-blue-600 text-white py-4 rounded-xl font-semibold hover:bg-blue-700 transition-colors flex items-center justify-center"onClick={() => startCharging(selectedStation)}disabled={selectedStation.availablePorts === 0}><Zap className="w-5 h-5 mr-2" />开始充电</button><button className="bg-gray-100 text-gray-700 py-4 rounded-xl font-semibold hover:bg-gray-200 transition-colors flex items-center justify-center"><Navigation className="w-5 h-5 mr-2" />导航前往</button></div>{/* 联系信息 */}<div className="bg-gray-50 p-4 rounded-xl"><div className="flex items-center justify-between"><span className="text-gray-600">客服电话</span><div className="flex items-center"><Phone className="w-4 h-4 text-blue-600 mr-2" /><span className="text-blue-600">400-123-4567</span></div></div></div></div>);};// 充电中视图const ChargingView = () => {const [currentTime, setCurrentTime] = useState(0);const [currentEnergy, setCurrentEnergy] = useState(0);const [currentCost, setCurrentCost] = useState(0);useEffect(() => {if (chargingSession) {const interval = setInterval(() => {setCurrentTime(prev => prev + 1);setCurrentEnergy(prev => prev + 0.5);setCurrentCost(prev => Math.round((prev + 0.6) * 100) / 100);}, 1000);return () => clearInterval(interval);}}, [chargingSession]);if (!chargingSession) return null;const formatTime = (seconds) => {const mins = Math.floor(seconds / 60);const secs = seconds % 60;return `${mins}:${secs.toString().padStart(2, '0')}`;};return (<div className="space-y-6">{/* 充电状态 */}<div className="bg-gradient-to-r from-green-500 to-green-600 text-white p-6 rounded-2xl text-center"><div className="w-20 h-20 bg-white/20 rounded-full flex items-center justify-center mx-auto mb-4"><Battery className="w-10 h-10" /></div><h2 className="text-xl font-bold mb-2">正在充电中</h2><p className="text-green-100">{chargingSession.station.name}</p></div>{/* 充电数据 */}<div className="grid grid-cols-3 gap-4"><div className="bg-white p-4 rounded-xl border border-gray-200 text-center"><div className="text-2xl font-bold text-blue-600">{formatTime(currentTime)}</div><div className="text-sm text-gray-600">充电时长</div></div><div className="bg-white p-4 rounded-xl border border-gray-200 text-center"><div className="text-2xl font-bold text-green-600">{currentEnergy.toFixed(1)}</div><div className="text-sm text-gray-600">已充电量(度)</div></div><div className="bg-white p-4 rounded-xl border border-gray-200 text-center"><div className="text-2xl font-bold text-orange-600">¥{currentCost}</div><div className="text-sm text-gray-600">当前费用</div></div></div>{/* 充电进度 */}<div className="bg-white p-6 rounded-xl border border-gray-200"><div className="flex justify-between items-center mb-4"><span className="text-gray-600">电池电量</span><span className="text-lg font-bold text-blue-600">75%</span></div><div className="w-full bg-gray-200 rounded-full h-4 mb-4"><div className="bg-gradient-to-r from-green-400 to-green-600 h-4 rounded-full transition-all duration-300" style={{width: '75%'}}></div></div><div className="flex justify-between text-sm text-gray-500"><span>预计剩余: 15分钟</span><span>目标: 90%</span></div></div>{/* 控制按钮 */}<div className="space-y-3"><button onClick={stopCharging}className="w-full bg-red-600 text-white py-4 rounded-xl font-semibold hover:bg-red-700 transition-colors flex items-center justify-center"><Square className="w-5 h-5 mr-2" />停止充电</button><button className="w-full bg-gray-100 text-gray-700 py-3 rounded-xl font-medium hover:bg-gray-200 transition-colors">延长充电时间</button></div></div>);};// 充电完成视图const CompleteView = () => (<div className="space-y-6 text-center"><div className="bg-green-50 p-8 rounded-2xl"><CheckCircle className="w-16 h-16 text-green-600 mx-auto mb-4" /><h2 className="text-2xl font-bold text-green-800 mb-2">充电完成</h2><p className="text-green-600">感谢使用充电服务</p></div><div className="bg-white p-6 rounded-xl border border-gray-200"><h3 className="font-bold text-lg mb-4">充电详情</h3><div className="space-y-3 text-left"><div className="flex justify-between"><span className="text-gray-600">充电时长</span><span className="font-medium">45分钟</span></div><div className="flex justify-between"><span className="text-gray-600">充电电量</span><span className="font-medium">28.5度</span></div><div className="flex justify-between"><span className="text-gray-600">充电费用</span><span className="font-medium text-blue-600">¥34.20</span></div><div className="flex justify-between"><span className="text-gray-600">获得积分</span><span className="font-medium text-orange-600">+34分</span></div></div></div><div className="space-y-3"><button onClick={() => setCurrentView('home')}className="w-full bg-blue-600 text-white py-4 rounded-xl font-semibold hover:bg-blue-700 transition-colors">返回首页</button><button onClick={() => setCurrentView('history')}className="w-full bg-gray-100 text-gray-700 py-3 rounded-xl font-medium hover:bg-gray-200 transition-colors">查看充电记录</button></div></div>);// 充电记录视图const HistoryView = () => (<div className="space-y-4"><div className="flex justify-between items-center"><h2 className="text-xl font-bold">充电记录</h2><button className="text-blue-600 text-sm">筛选</button></div><div className="space-y-4">{chargingHistory.map(record => (<div key={record.id} className="bg-white p-4 rounded-xl border border-gray-200"><div className="flex justify-between items-start mb-3"><div><h4 className="font-semibold text-gray-800">{record.station}</h4><p className="text-sm text-gray-500">{record.date}</p></div><span className="bg-green-100 text-green-600 px-2 py-1 rounded text-sm">{record.status}</span></div><div className="grid grid-cols-3 gap-4 text-sm"><div><span className="text-gray-500">时长</span><div className="font-medium">{record.duration}</div></div><div><span className="text-gray-500">电量</span><div className="font-medium">{record.energy}</div></div><div><span className="text-gray-500">费用</span><div className="font-medium text-blue-600">{record.cost}</div></div></div></div>))}</div></div>);// 个人中心视图const ProfileView = () => (<div className="space-y-6">{/* 用户信息 */}<div className="bg-white p-6 rounded-2xl border border-gray-200"><div className="flex items-center mb-4"><div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mr-4"><User className="w-8 h-8 text-blue-600" /></div><div><h3 className="font-bold text-lg">{user.name}</h3><p className="text-gray-500">手机号: 138****8888</p></div></div><div className="grid grid-cols-2 gap-4"><div className="text-center p-4 bg-blue-50 rounded-xl"><div className="text-xl font-bold text-blue-600">¥{user.balance}</div><div className="text-sm text-blue-600">账户余额</div></div><div className="text-center p-4 bg-orange-50 rounded-xl"><div className="text-xl font-bold text-orange-600">{user.points}</div><div className="text-sm text-orange-600">积分余额</div></div></div></div>{/* 功能菜单 */}<div className="space-y-2">{[{ icon: CreditCard, label: '我的钱包', desc: '余额充值、提现' },{ icon: Car, label: '我的车辆', desc: '车辆管理、绑定' },{ icon: Settings, label: '设置', desc: '账户设置、隐私' },{ icon: Phone, label: '客服帮助', desc: '在线客服、常见问题' }].map((item, index) => (<div key={index} className="bg-white p-4 rounded-xl border border-gray-200 hover:border-blue-300 transition-colors cursor-pointer"><div className="flex items-center"><div className="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center mr-4"><item.icon className="w-5 h-5 text-gray-600" /></div><div className="flex-1"><h4 className="font-medium">{item.label}</h4><p className="text-sm text-gray-500">{item.desc}</p></div><ChevronRight className="w-5 h-5 text-gray-400" /></div></div>))}</div></div>);// 渲染当前视图const renderCurrentView = () => {switch (currentView) {case 'home': return <HomeView />;case 'map': return <MapView />;case 'station': return <StationView />;case 'charging': return <ChargingView />;case 'complete': return <CompleteView />;case 'history': return <HistoryView />;case 'profile': return <ProfileView />;default: return <HomeView />;}};return (<div className="max-w-md mx-auto bg-gray-50 min-h-screen">{/* 顶部导航栏 */}<div className="bg-white p-4 flex items-center justify-between border-b border-gray-200"><h1 className="text-xl font-bold text-gray-800">{currentView === 'home' && '充电'}{currentView === 'map' && '找充电桩'}{currentView === 'station' && '充电桩详情'}{currentView === 'charging' && '充电中'}{currentView === 'complete' && '充电完成'}{currentView === 'history' && '充电记录'}{currentView === 'profile' && '个人中心'}</h1>{currentView !== 'home' && (<button onClick={() => setCurrentView('home')}className="text-blue-600 font-medium">返回</button>)}</div>{/* 主要内容 */}<div className="p-4 pb-24">{renderCurrentView()}</div>{/* 底部导航栏 */}<div className="fixed bottom-0 left-1/2 transform -translate-x-1/2 w-full max-w-md bg-white border-t border-gray-200"><div className="flex justify-around py-2">{[{ icon: Home, label: '首页', view: 'home' },{ icon: MapPin, label: '找桩', view: 'map' },{ icon: History, label: '记录', view: 'history' },{ icon: User, label: '我的', view: 'profile' }].map((item, index) => (<buttonkey={index}onClick={() => setCurrentView(item.view)}className={`flex flex-col items-center py-2 px-4 ${currentView === item.view ? 'text-blue-600' : 'text-gray-500'}`}><item.icon className="w-6 h-6 mb-1" /><span className="text-xs">{item.label}</span></button>))}</div></div></div>);
};export default ChargingStationApp;

http://www.xdnf.cn/news/18834.html

相关文章:

  • 自动修改excel 自动统计文件名称插入 excel辅助工具
  • 【基础-单选】向服务器提交表单数据,以下哪种请求方式比较合适
  • 处理端口和 IP 地址
  • 基于Java企业商城网站
  • 彻底解决PyCharm中Matplotlib无法显示图形及中文乱码问题
  • C-JSON接口的使用
  • “无人驾驶与人”之浅析
  • 技术攻坚与安全兜底——消防智能仓储立库管理系统的国产化硬核实力
  • **FastAPI + Pydantic v2 + JSON‑RPC 2.0**,实现 A2A 规范核心方法
  • 18 继续学习
  • SpringBoot的条件装配原理
  • 量子计算驱动的Python医疗诊断编程前沿展望(下)
  • localhost和127.0.0.1的区别
  • 不再让Windows更新!Edge游戏助手卸载及关闭自动更新
  • 雪花算法数据库主键
  • Shell 学习笔记 - Shell 三剑客篇
  • 【ABAP4】基本语法1
  • CI/CD企业案例详解
  • Linux下usb设备驱动涉及的结构体
  • 记一次生产环境Hbase填坑之路、Hbase客户端登陆、kerberos认证、端口列表、Pod上手撕代码【Hbase最佳实践】
  • 酶 EC number 预测工具CLEAN的安装和使用
  • Java 线程池详解:原理、使用与源码深度解析
  • 从全栈开发到微服务架构:一次真实的Java面试实录
  • 【图像处理基石】如何把非笑脸转为笑脸?
  • Git连接Github远程仓库的代理设置
  • Java:HashSet的使用
  • Linux shell脚本条件循环
  • 基础篇(下):神经网络与反向传播(程序员视角)
  • 【论文阅读 | arXiv 2025 | WaveMamba:面向RGB-红外目标检测的小波驱动Mamba融合方法】
  • Multitouch for mac 触控板手势增强软件