React Native鸿蒙跨平台代码如何通过严格定义Service类型确保数据一致性,使用Hooks进行状态管理,实现单向数据流
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
本项目采用React Native函数式组件架构,以LifeServiceApp为核心组件,实现了生活服务助手应用的完整功能流程。架构设计遵循模块化原则,将数据结构、状态管理和业务逻辑清晰分离,便于维护和扩展。
核心技术栈
- React Native:跨平台移动应用开发框架,支持iOS、Android和鸿蒙系统
- TypeScript:提供类型安全,增强代码可维护性和开发体验
- Hooks API:使用useState进行状态管理,简化组件逻辑
- Flexbox:实现响应式布局,适配不同屏幕尺寸
- Base64图标:内置图标资源,减少网络请求,提升加载速度
- Dimensions API:获取屏幕尺寸,实现精细化布局控制
生活服务类型(Service)
type Service = {
id: string;
name: string;
category: '家政清洁' | '维修服务' | '美容美发' | '课程体验';
price: number;
image: string;
description: string;
duration?: string;
isAvailable?: boolean;
};
该类型设计全面,包含了生活服务的核心信息:
id:唯一标识符,确保数据唯一性name:服务名称,便于用户识别category:服务分类,使用联合类型确保类型安全price:价格信息,直接影响购买决策image:服务图片,提升用户体验description:服务描述,提供详细信息duration:服务时长,可选字段,增强服务透明度isAvailable:是否可预约,可选字段,影响预约可行性
核心状态
应用使用useState钩子管理一个核心状态:
services:生活服务列表,使用常量状态,包含多种类型的生活服务
更新机制
- 服务详情:通过handleServiceDetail函数,根据服务ID查找服务信息并展示
- 预约服务:通过handleBookService函数,预约服务,同时检查可预约状态
- 用户交互:通过Alert组件提供操作确认和信息提示
状态管理
- 不可变数据模式:使用find方法查找服务,避免直接修改原状态
- 状态验证:在进行操作前,通过find方法验证服务是否存在
- 预约检查:在预约服务前检查服务可预约状态,确保操作可行性
- 用户反馈:操作完成后,通过Alert组件提供明确的成功提示
- 数据过滤:使用filter方法筛选可预约服务,实现智能推荐
业务流程
- 服务展示:展示生活服务列表,包含热门推荐和分类导航
- 服务详情:查看服务详细信息,包括名称、价格、描述等
- 预约服务:预约可预约的服务,支持确认或取消
- 分类浏览:按服务分类浏览不同类型的生活服务
const handleBookService = (serviceId: string) => {
const service = services.find(s => s.id === serviceId);
if (service) {
if (!service.isAvailable) {
Alert.alert('提示', '该服务暂时不可预约');
return;
}
Alert.alert(
'预约确认',
`确认预约 ${service.name} 吗?\n` +
`价格: ¥${service.price}\n` +
`时长: ${service.duration}`,
[
{ text: '取消', style: 'cancel' },
{ text: '确认预约', onPress: () => Alert.alert('提示', '预约成功!') }
]
);
}
};
数据流
- 单向数据流:状态 → 视图 → 用户操作 → 状态更新
- 数据过滤:在渲染时使用filter方法筛选可预约服务,确保推荐准确性
- 业务逻辑封装:将复杂操作逻辑封装在专用函数中,提高代码可读性
- 用户交互反馈:使用Alert组件提供操作确认和信息提示,提升用户体验
- 预约验证:在预约服务前验证服务可预约状态,确保操作可行性
组件
- 核心组件:SafeAreaView、View、Text、ScrollView、TouchableOpacity等在鸿蒙系统上有对应实现
- API兼容性:Dimensions API在鸿蒙系统中可正常使用,确保布局适配
- Alert组件:鸿蒙系统支持Alert组件的基本功能,但样式可能有所差异
- ScrollView:横向ScrollView在鸿蒙系统中可正常使用,确保热门服务展示
资源管理
- Base64图标:在鸿蒙系统中同样支持,可减少网络请求,提升性能
- 内存管理:鸿蒙系统对内存使用更为严格,需注意资源释放
- 计算性能:对于服务过滤和查找等操作,鸿蒙系统的处理性能与其他平台相当
性能
- 渲染性能:避免不必要的重渲染,合理使用React.memo;对于长服务列表,建议使用FlatList替代ScrollView;优化组件结构,减少嵌套层级
- 数据处理:缓存计算结果,避免重复计算;优化服务查找算法,特别是可预约服务筛选;考虑使用useMemo缓存计算结果,提高性能
- 内存管理:及时释放不再使用的资源;避免内存泄漏,特别是在处理多个服务时;合理使用缓存策略,平衡性能和内存占用
- 条件渲染:使用Platform API检测平台,针对不同平台使用不同实现
- 样式适配:考虑鸿蒙系统的设计规范,调整UI样式以符合平台特性
- 权限处理:鸿蒙系统的权限管理与Android有所不同,需单独处理
- 鸿蒙特性:充分利用鸿蒙系统的分布式能力,实现多设备协同
- 图标资源:针对鸿蒙系统的图标规范,调整Base64图标资源
类型定义
- 使用枚举类型:将服务分类、服务时长等使用枚举类型替代字符串,提高代码可读性和可维护性
- 类型扩展:考虑使用接口继承,增强类型系统的表达能力
- 类型守卫:添加更多类型守卫,确保运行时类型安全
- 国际化支持:考虑添加国际化支持,特别是服务分类等术语
状态管理
- 状态分离:对于复杂状态,考虑使用useReducer或状态管理库(如Redux、Zustand)
- 状态持久化:实现状态持久化,使用AsyncStorage存储服务和预约数据
- 计算属性:使用useMemo缓存计算结果,避免重复计算
- 批量操作:支持批量管理预约服务,提高用户体验
组件化
- 组件拆分:将大型组件拆分为更小的可复用组件,如ServiceCard、CategorySection、PopularItem等
- 自定义Hook:提取重复的状态逻辑到自定义Hook,如useServiceManager、useBooking等
- 高阶组件:使用高阶组件处理横切关注点,如错误边界、加载状态等
- 表单组件:封装服务详情和预约组件,提高代码复用性
业务逻辑
- 服务层分离:将业务逻辑分离到服务层,提高代码可测试性
- 错误处理:增强错误处理机制,提供更友好的错误提示
- 实时更新:考虑添加实时服务可预约状态更新,提升用户体验
- 智能推荐:实现更智能的服务推荐算法,基于用户偏好和浏览历史
代码组织
- 模块化设计:采用模块化设计,分离平台特定代码
- 配置管理:使用配置文件管理不同平台的差异
- 目录结构:合理组织目录结构,便于维护和扩展
- 安全分区:对于用户数据等敏感信息,采用安全分区存储
本项目展示了如何使用React Native和TypeScript构建一个功能完整的生活服务助手应用。通过合理的架构设计、类型定义和状态管理,实现了跨平台的一致性体验。
随着React Native和鸿蒙系统的不断发展,跨端开发将会变得更加成熟和高效。未来可以考虑:
- 使用React Native 0.70+版本:利用新的架构特性,如Fabric渲染器和Turbo Modules,提升应用性能
- 探索鸿蒙原生能力:充分利用鸿蒙系统的分布式能力,实现多设备协同和更丰富的功能
- 引入现代化状态管理:使用Redux Toolkit或Zustand等现代状态管理库,简化状态管理
- 实现PWA支持:扩展应用的使用场景,支持Web平台
- 集成AI能力:引入AI技术,如智能服务推荐、个性化预约建议等,提升应用智能化水平
- 实时数据同步:实现服务可预约状态和价格的实时同步,确保数据准确性
- 多语言支持:添加多语言支持,提升应用的全球适配能力
通过持续的技术迭代和优化,可以构建更加稳定、高效、智能的生活服务助手应用,为用户提供更优质的生活服务预约体验。
本地生活服务类应用的核心价值在于“场景化服务+即时响应”,而跨端适配能力直接决定应用的覆盖范围与用户体验上限。React Native 凭借“一次开发、多端部署”的技术特性,成为连接 iOS、Android 与鸿蒙(HarmonyOS)系统的最优技术选型。本文以生活服务助手应用为例,从本地生活服务场景的数据模型设计、鸿蒙风格 UI 实现、跨端业务逻辑兼容等维度,深度解析 React Native 对接鸿蒙系统的技术内核与本地生活服务场景的落地最佳实践。
一、跨端生活服务应用
本生活服务助手应用聚焦家政清洁、维修服务、美容美发、课程体验四大核心本地生活服务场景,覆盖服务展示、预约状态校验、在线预约等完整服务链路,整体架构遵循 React Native 组件化开发范式,同时深度契合鸿蒙系统的设计语言与本地生活服务类应用的交互规范。从技术底层来看,应用基于 React 函数式组件 + TypeScript 构建,这种组合既保证了生活服务数据的类型安全,又能最大化跨端复用率,是 React Native 适配鸿蒙系统本地生活服务类应用的理想技术底座。
1. 生活服务跨端
本地生活服务类应用涉及多维度的服务属性(服务时长、可预约状态、服务类型等),统一且精准的强类型数据模型是避免多端行为不一致的关键。代码中通过 TypeScript 严格定义了生活服务的核心数据结构,覆盖本地生活服务全场景的业务属性:
// 生活服务核心数据模型
type Service = {
id: string;
name: string;
category: '家政清洁' | '维修服务' | '美容美发' | '课程体验';
price: number;
image: string;
description: string;
duration?: string; // 服务时长
isAvailable?: boolean; // 是否可预约
};
这种场景化的强类型定义不仅在开发阶段提供语法校验和智能提示,更关键的是在鸿蒙系统适配时,能够与 ArkTS 的类型系统形成天然映射。相较于纯 JavaScript 开发,TypeScript 可有效规避因数据类型模糊导致的服务信息展示错误——尤其是在鸿蒙这类面向全场景智慧终端的操作系统中,类型安全能大幅降低多设备适配的调试成本,确保服务时长、可预约状态、价格等核心生活服务数据在不同终端的一致性。
2. 状态管理:
应用采用 React 内置的 useState Hook 管理核心服务状态,结合不可变数据模式实现生活服务信息的跨端展示:
const [services] = useState<Service[]>([
{
id: '1',
name: '深度家庭清洁',
category: '家政清洁',
price: 199,
image: '🧹',
description: '专业清洁团队,彻底打扫每个角落',
duration: '3小时',
isAvailable: true
},
// 其他生活服务数据
]);
这种轻量级状态管理方案完全适配本地生活服务类跨端开发场景,相较于 Redux 等重型状态库,useState 无需额外的中间件和适配层,能够直接在 React Native 支持的所有平台(包括鸿蒙)上稳定运行。从鸿蒙系统的视角来看,useState 的状态管理逻辑与 ArkUI 的 @State 装饰器在设计理念上高度契合,开发者无需切换思维模式即可完成跨端状态管理,大幅降低了鸿蒙适配的学习成本。
React Native 的核心价值在于通过统一的组件抽象层,屏蔽不同平台的 UI 实现差异。本应用在 UI 层的设计深度复刻了鸿蒙系统的视觉风格与本地生活服务类应用交互规范,同时保证多端体验的一致性。
1. Flex 布局
应用基于 React Native 的 Flex 布局系统构建整体界面,通过 Dimensions.get('window') 获取设备宽高,实现对不同尺寸鸿蒙设备(手机、平板、智慧屏)的自适应:
const { width, height } = Dimensions.get('window');
相较于鸿蒙系统的 DirectionalLayout 和 GridLayout,React Native 的 Flex 布局具备更强的跨端兼容性,通过 flexDirection、justifyContent、flexWrap 等属性,能够精准还原鸿蒙系统的生活服务界面布局逻辑。例如生活服务网格布局的实现:
<View style={styles.servicesGrid}>
{services
.filter(s => s.category === category)
.map(service => (
<TouchableOpacity
key={service.id}
style={styles.serviceItem}
onPress={() => handleServiceDetail(service.id)}
>
{/* 生活服务展示内容 */}
</TouchableOpacity>
))
}
</View>
这段代码通过 flexDirection: 'row'、justifyContent: 'space-between' 和 flexWrap: 'wrap' 实现了鸿蒙系统特有的生活服务网格布局效果,结合 width: '48%' 的样式定义,在不同尺寸的鸿蒙设备上都能保持服务卡片的合理排列,无需针对鸿蒙系统做额外的布局适配。
2. 视觉样式:
应用通过 StyleSheet.create 定义样式表,深度适配鸿蒙系统的本地生活服务设计规范,核心体现在以下几个维度:
- 生活服务色彩体系:采用鸿蒙系统的自然绿系主色调(
#059669、#065f46),搭配功能性色彩区分服务状态(可预约-绿色、已满-红色),符合鸿蒙系统本地生活应用“清新、实用”的视觉设计理念 - 圆角与阴影:使用
borderRadius: 12实现鸿蒙风格的大圆角设计,通过elevation(Android)和shadow(iOS)属性适配鸿蒙系统的阴影效果,兼顾生活服务界面的层次感与跨端一致性 - 服务状态标签样式:通过动态样式绑定实现鸿蒙风格的预约状态标签,同时强化服务时长的视觉层级:
<View style={[
styles.statusTag,
{ backgroundColor: service.isAvailable ? '#10b981' : '#ef4444' }
]}>
<Text style={styles.statusTagText}>
{service.isAvailable ? '可约' : '已满'}
</Text>
</View>
<Text style={styles.largeServiceDuration}>时长: {service.duration}</Text>
这种样式设计方案完全基于 React Native 的标准 API 实现,在鸿蒙系统中能够通过 React Native 的渲染层自动转换为原生样式——backgroundColor 对应鸿蒙的 background-color,borderRadius 对应鸿蒙的 border-radius,无需编写平台特定代码。
3. 交互组件:
应用中所有交互组件均基于 React Native 基础组件封装,同时适配鸿蒙系统的本地生活服务交互规范:
- SafeAreaView:对应鸿蒙系统的
SafeArea组件,适配刘海屏、挖孔屏等异形屏,保证生活服务界面在鸿蒙不同终端设备上的完整性 - ScrollView (horizontal):与鸿蒙的
List组件(横向模式)逻辑一致,实现可预约热门服务的横向滚动展示,适配鸿蒙系统的滑动交互逻辑 - TouchableOpacity (disabled):替代鸿蒙的
Button组件(禁用态),实现不可预约服务按钮的不可点击状态,符合鸿蒙的交互规范 - Alert:对应鸿蒙的
TextDialog组件,实现服务详情、预约确认等弹窗交互,保持与鸿蒙原生生活服务应用一致的交互体验
以生活服务预约交互为例,代码通过状态判断实现鸿蒙风格的预约校验逻辑:
<TouchableOpacity
style={[
styles.bookButton,
{ backgroundColor: service.isAvailable ? '#3b82f6' : '#94a3b8' }
]}
onPress={() => handleBookService(service.id)}
disabled={!service.isAvailable}
>
<Text style={styles.bookButtonText}>
{service.isAvailable ? '立即预约' : '暂不可约'}
</Text>
</TouchableOpacity>
这种交互逻辑完全基于 React Native 的跨端 API 实现,在鸿蒙系统中能够保持与原生生活服务应用一致的交互体验,无需针对鸿蒙系统做特殊处理。
除了 UI 层的适配,本地生活服务业务逻辑的跨端兼容性是 React Native 开发的核心。本应用的核心业务逻辑包括生活服务详情展示、预约状态校验、分类筛选等,这些逻辑完全基于 JavaScript/TypeScript 实现,天然具备跨端运行能力。
1. 分类筛选
应用实现了基于服务分类的精准筛选逻辑,通过纯函数过滤实现不同生活服务类别的展示:
{['家政清洁', '维修服务', '美容美发', '课程体验'].map(category => (
<View key={category} style={styles.categorySection}>
{/* 分类标题 */}
<View style={styles.servicesGrid}>
{services
.filter(s => s.category === category)
.map(service => (
{/* 生活服务展示 */}
))
}
</View>
</View>
))}
该逻辑完全基于纯函数实现,不依赖任何平台特定 API,在 React Native 支持的所有平台(包括鸿蒙)上都能稳定运行。值得注意的是,代码中使用 Array.filter 等标准 JavaScript 方法处理生活服务数据,这些方法在鸿蒙系统的 JS 引擎中能够无缝执行,体现了 React Native 跨端开发“一次编写,多端复用”的核心价值。
2. 预约状态
应用针对本地生活服务场景实现了鸿蒙风格的预约状态校验交互,包含服务可预约状态判断与操作反馈:
const handleBookService = (serviceId: string) => {
const service = services.find(s => s.id === serviceId);
if (service) {
if (!service.isAvailable) {
Alert.alert('提示', '该服务暂时不可预约');
return;
}
Alert.alert(
'预约确认',
`确认预约 ${service.name} 吗?\n` +
`价格: ¥${service.price}\n` +
`时长: ${service.duration}`,
[
{ text: '取消', style: 'cancel' },
{ text: '确认预约', onPress: () => Alert.alert('提示', '预约成功!') }
]
);
}
};
这种交互逻辑基于纯 JavaScript 实现,能够有效保证预约操作的跨端一致性,同时在鸿蒙系统中,Alert.alert 的回调函数能够被 JS 引擎高效执行,确保生活服务操作的即时反馈。
3. 可预约服务筛选
应用实现了基于 isAvailable 属性的可预约生活服务筛选,用于展示核心热门服务:
{services.filter(s => s.isAvailable).map(service => (
<TouchableOpacity
key={service.id}
style={styles.popularItem}
onPress={() => handleServiceDetail(service.id)}
>
{/* 可预约生活服务展示 */}
</TouchableOpacity>
))}
这种无副作用的纯函数筛选方式,不仅符合 React 的设计理念,更重要的是在跨端场景下,能够避免因不同平台的运行时差异导致的筛选结果不一致。对于鸿蒙系统而言,这类纯逻辑代码无需任何适配即可直接运行,是本地生活服务类跨端开发的最优实践。
从本应用的实现来看,React Native 对接鸿蒙系统本地生活服务场景的核心在于“抽象层适配 + 生活服务体验兼容”,具体体现在以下几个维度:
-
JS 引擎层生活服务兼容:鸿蒙系统内置了符合 ECMAScript 标准的 JavaScript 引擎,能够直接执行 React Native 的 JS 代码,这是跨端运行的底层基础。本应用中所有的生活服务业务逻辑代码(服务筛选、预约校验、详情展示)均运行在 JS 引擎层,无需任何修改即可在鸿蒙系统中执行,保证了生活服务逻辑的跨端一致性。
-
组件映射层生活服务适配:React Native 通过自定义渲染器,将 React 组件(View、Text、TouchableOpacity 等)映射为鸿蒙系统的原生组件。例如横向
ScrollView会被转换为鸿蒙的横向List组件,TouchableOpacity (disabled)会被转换为鸿蒙的禁用态Button组件,这种映射关系由 React Native 的鸿蒙适配层自动完成,开发者无需关注底层实现细节,只需专注于生活服务业务逻辑开发。 -
样式转换层生活服务规范适配:React Native 的 StyleSheet 样式会被自动转换为鸿蒙系统的原生样式,本应用中定义的所有鸿蒙生活服务风格样式(自然绿主调、服务状态色彩、服务卡片样式)都能通过这一层完成自动转换,保证了生活服务 UI 风格在鸿蒙系统中的一致性。
-
生活服务体验跨端兼容:应用中所有交互逻辑均基于 React Native 的标准 API 实现,这些 API 在鸿蒙系统中会被替换为对应的原生 API 调用,例如
Alert.alert对应鸿蒙的TextDialog,TouchableOpacity (disabled)对应鸿蒙的禁用态Button,确保了生活服务体验在不同平台的一致性。
本生活服务助手应用的实现完整展现了 React Native 在鸿蒙跨端本地生活服务开发领域的技术优势,核心要点可总结为:
- 强类型设计保障生活服务数据一致性:TypeScript 场景化类型定义不仅提升代码质量,更能与鸿蒙 ArkTS 形成类型映射,降低本地生活服务场景跨端适配成本,是生活服务类应用跨端开发的基础保障
- 纯逻辑开发最大化生活服务代码复用率:服务筛选、预约校验、详情展示等核心生活服务逻辑采用纯 JavaScript/TypeScript 实现,无需针对鸿蒙系统做特殊修改,大幅提升开发效率
- 标准 API 适配鸿蒙生活服务生态:基于 React Native 标准组件和 API 开发,通过底层适配层自动对接鸿蒙原生能力,兼顾开发效率与本地生活服务场景的原生体验
真实演示案例代码:
// App.tsx
import React, { useState } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Dimensions, Alert } from 'react-native';
// Base64 图标库
const ICONS_BASE64 = {
cleaning: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
repair: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
beauty: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
course: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
plumbing: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
massage: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
tutor: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
electrician: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};
const { width, height } = Dimensions.get('window');
// 生活服务类型
type Service = {
id: string;
name: string;
category: '家政清洁' | '维修服务' | '美容美发' | '课程体验';
price: number;
image: string;
description: string;
duration?: string; // 服务时长
isAvailable?: boolean; // 是否可预约
};
// 生活服务助手应用组件
const LifeServiceApp: React.FC = () => {
const [services] = useState<Service[]>([
{
id: '1',
name: '深度家庭清洁',
category: '家政清洁',
price: 199,
image: '🧹',
description: '专业清洁团队,彻底打扫每个角落',
duration: '3小时',
isAvailable: true
},
{
id: '2',
name: '水电维修服务',
category: '维修服务',
price: 89,
image: '🔧',
description: '持证上岗,快速解决水电问题',
duration: '1-2小时',
isAvailable: true
},
{
id: '3',
name: '专业面部护理',
category: '美容美发',
price: 299,
image: '💆',
description: '高端护肤品,享受SPA级护理体验',
duration: '90分钟',
isAvailable: false
},
{
id: '4',
name: '钢琴一对一课程',
category: '课程体验',
price: 150,
image: '🎹',
description: '资深老师指导,因材施教',
duration: '60分钟',
isAvailable: true
},
{
id: '5',
name: '管道疏通服务',
category: '维修服务',
price: 129,
image: '🚰',
description: '专业设备,快速疏通各类管道',
duration: '1-3小时',
isAvailable: true
},
{
id: '6',
name: '全身精油按摩',
category: '美容美发',
price: 199,
image: '🧖',
description: '缓解疲劳,促进血液循环',
duration: '60分钟',
isAvailable: true
}
]);
const getCategoryColor = (category: string) => {
switch (category) {
case '家政清洁': return '#8b5cf6';
case '维修服务': return '#3b82f6';
case '美容美发': return '#f59e0b';
case '课程体验': return '#10b981';
default: return '#64748b';
}
};
const handleServiceDetail = (serviceId: string) => {
const service = services.find(s => s.id === serviceId);
if (service) {
Alert.alert(
'服务详情',
`名称: ${service.name}\n` +
`分类: ${service.category}\n` +
`时长: ${service.duration}\n` +
`价格: ¥${service.price}\n` +
`状态: ${service.isAvailable ? '可预约' : '已满'}\n` +
`描述: ${service.description}`,
[{ text: '确定', style: 'cancel' }]
);
}
};
const handleBookService = (serviceId: string) => {
const service = services.find(s => s.id === serviceId);
if (service) {
if (!service.isAvailable) {
Alert.alert('提示', '该服务暂时不可预约');
return;
}
Alert.alert(
'预约确认',
`确认预约 ${service.name} 吗?\n` +
`价格: ¥${service.price}\n` +
`时长: ${service.duration}`,
[
{ text: '取消', style: 'cancel' },
{ text: '确认预约', onPress: () => Alert.alert('提示', '预约成功!') }
]
);
}
};
return (
<SafeAreaView style={styles.container}>
{/* 头部 */}
<View style={styles.header}>
<Text style={styles.title}>生活服务助手</Text>
<Text style={styles.subtitle}>便捷预约,品质生活</Text>
</View>
<ScrollView style={styles.content}>
{/* 热门推荐 */}
<View style={styles.popularCard}>
<Text style={styles.sectionTitle}>热门服务</Text>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<View style={styles.popularRow}>
{services.filter(s => s.isAvailable).map(service => (
<TouchableOpacity
key={service.id}
style={styles.popularItem}
onPress={() => handleServiceDetail(service.id)}
>
<Text style={styles.serviceImage}>{service.image}</Text>
<Text style={styles.serviceName}>{service.name}</Text>
<Text style={styles.serviceDuration}>{service.duration}</Text>
<Text style={styles.servicePrice}>¥{service.price}</Text>
<View style={styles.availableTag}>
<Text style={styles.availableTagText}>可约</Text>
</View>
</TouchableOpacity>
))}
</View>
</ScrollView>
</View>
{/* 服务分类 */}
<View style={styles.categoriesCard}>
<Text style={styles.sectionTitle}>服务分类</Text>
{['家政清洁', '维修服务', '美容美发', '课程体验'].map(category => (
<View key={category} style={styles.categorySection}>
<View style={[
styles.categoryHeader,
{ borderLeftColor: getCategoryColor(category) }
]}>
<Text style={styles.categoryTitle}>{category}</Text>
</View>
<View style={styles.servicesGrid}>
{services
.filter(s => s.category === category)
.map(service => (
<TouchableOpacity
key={service.id}
style={styles.serviceItem}
onPress={() => handleServiceDetail(service.id)}
>
<Text style={styles.largeServiceImage}>{service.image}</Text>
<Text style={styles.largeServiceName}>{service.name}</Text>
<Text style={styles.largeServiceDuration}>时长: {service.duration}</Text>
<Text style={styles.largeServiceDesc}>{service.description}</Text>
<View style={styles.priceRow}>
<Text style={styles.largeServicePrice}>¥{service.price}</Text>
<View style={[
styles.statusTag,
{ backgroundColor: service.isAvailable ? '#10b981' : '#ef4444' }
]}>
<Text style={styles.statusTagText}>
{service.isAvailable ? '可约' : '已满'}
</Text>
</View>
</View>
<TouchableOpacity
style={[
styles.bookButton,
{ backgroundColor: service.isAvailable ? '#3b82f6' : '#94a3b8' }
]}
onPress={() => handleBookService(service.id)}
disabled={!service.isAvailable}
>
<Text style={styles.bookButtonText}>
{service.isAvailable ? '立即预约' : '暂不可约'}
</Text>
</TouchableOpacity>
</TouchableOpacity>
))
}
</View>
</View>
))}
</View>
{/* 生活贴士 */}
<View style={styles.tipsCard}>
<Text style={styles.sectionTitle}>生活小贴士</Text>
<View style={styles.tipItem}>
<Text style={styles.tipEmoji}>🏠</Text>
<View style={styles.tipContent}>
<Text style={styles.tipTitle}>定期清洁</Text>
<Text style={styles.tipDesc}>每月深度清洁,保持家居卫生</Text>
</View>
</View>
<View style={styles.tipItem}>
<Text style={styles.tipEmoji}>🔧</Text>
<View style={styles.tipContent}>
<Text style={styles.tipTitle}>及时维修</Text>
<Text style={styles.tipDesc}>发现问题及时处理,避免小问题变大</Text>
</View>
</View>
<View style={styles.tipItem}>
<Text style={styles.tipEmoji}>💆</Text>
<View style={styles.tipContent}>
<Text style={styles.tipTitle}>自我护理</Text>
<Text style={styles.tipDesc}>定期护理放松,保持身心健康</Text>
</View>
</View>
</View>
{/* 使用说明 */}
<View style={styles.infoCard}>
<Text style={styles.sectionTitle}>使用说明</Text>
<Text style={styles.infoText}>• 在线预约各类生活服务</Text>
<Text style={styles.infoText}>• 支持在线支付,安全便捷</Text>
<Text style={styles.infoText}>• 实时查看服务人员信息</Text>
<Text style={styles.infoText}>• 服务不满意可申请退款</Text>
</View>
</ScrollView>
{/* 底部导航 */}
<View style={styles.bottomNav}>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>🧹</Text>
<Text style={styles.navText}>清洁</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>🔧</Text>
<Text style={styles.navText}>维修</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem}>
<Text style={styles.navIcon}>💆</Text>
<Text style={styles.navText}>美容</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.navItem, styles.activeNavItem]}>
<Text style={styles.navIcon}>👤</Text>
<Text style={styles.navText}>我的</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecfdf5',
},
header: {
flexDirection: 'column',
padding: 16,
backgroundColor: '#ffffff',
borderBottomWidth: 1,
borderBottomColor: '#d1fae5',
},
title: {
fontSize: 20,
fontWeight: 'bold',
color: '#065f46',
marginBottom: 4,
},
subtitle: {
fontSize: 14,
color: '#059669',
},
content: {
flex: 1,
marginTop: 12,
},
popularCard: {
backgroundColor: '#ffffff',
marginHorizontal: 16,
marginBottom: 12,
borderRadius: 12,
padding: 16,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
sectionTitle: {
fontSize: 16,
fontWeight: '600',
color: '#065f46',
marginBottom: 12,
},
popularRow: {
flexDirection: 'row',
},
popularItem: {
width: 120,
backgroundColor: '#ecfdf5',
borderRadius: 12,
padding: 12,
marginRight: 12,
alignItems: 'center',
},
serviceImage: {
fontSize: 28,
marginBottom: 8,
},
serviceName: {
fontSize: 12,
fontWeight: '500',
color: '#065f46',
marginBottom: 4,
textAlign: 'center',
},
serviceDuration: {
fontSize: 10,
color: '#059669',
marginBottom: 4,
},
servicePrice: {
fontSize: 14,
fontWeight: 'bold',
color: '#059669',
},
availableTag: {
backgroundColor: '#10b981',
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: 12,
position: 'absolute',
top: 8,
right: 8,
},
availableTagText: {
fontSize: 10,
color: '#ffffff',
fontWeight: '600',
},
categoriesCard: {
backgroundColor: '#ffffff',
marginHorizontal: 16,
marginBottom: 12,
borderRadius: 12,
padding: 16,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
categorySection: {
marginBottom: 16,
},
categoryHeader: {
flexDirection: 'row',
alignItems: 'center',
borderLeftWidth: 4,
paddingLeft: 12,
marginBottom: 12,
},
categoryTitle: {
fontSize: 14,
fontWeight: '600',
color: '#065f46',
},
servicesGrid: {
flexDirection: 'row',
justifyContent: 'space-between',
flexWrap: 'wrap',
},
serviceItem: {
width: '48%',
backgroundColor: '#ecfdf5',
borderRadius: 12,
padding: 12,
marginBottom: 12,
},
largeServiceImage: {
fontSize: 32,
marginBottom: 8,
textAlign: 'center',
},
largeServiceName: {
fontSize: 14,
fontWeight: '600',
color: '#065f46',
marginBottom: 4,
textAlign: 'center',
},
largeServiceDuration: {
fontSize: 10,
color: '#059669',
marginBottom: 4,
textAlign: 'center',
},
largeServiceDesc: {
fontSize: 12,
color: '#64748b',
marginBottom: 8,
textAlign: 'center',
lineHeight: 16,
},
priceRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 8,
},
largeServicePrice: {
fontSize: 16,
fontWeight: 'bold',
color: '#059669',
},
statusTag: {
paddingHorizontal: 6,
paddingVertical: 2,
borderRadius: 8,
marginLeft: 8,
},
statusTagText: {
fontSize: 10,
color: '#ffffff',
fontWeight: '600',
},
bookButton: {
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 16,
alignItems: 'center',
},
bookButtonText: {
color: '#ffffff',
fontSize: 12,
fontWeight: '500',
},
tipsCard: {
backgroundColor: '#ffffff',
marginHorizontal: 16,
marginBottom: 12,
borderRadius: 12,
padding: 16,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
tipItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: '#d1fae5',
},
tipEmoji: {
fontSize: 20,
width: 30,
},
tipContent: {
flex: 1,
},
tipTitle: {
fontSize: 14,
fontWeight: '600',
color: '#065f46',
marginBottom: 2,
},
tipDesc: {
fontSize: 12,
color: '#64748b',
},
infoCard: {
backgroundColor: '#ffffff',
marginHorizontal: 16,
marginBottom: 80,
borderRadius: 12,
padding: 16,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
infoText: {
fontSize: 14,
color: '#64748b',
lineHeight: 20,
marginBottom: 4,
},
bottomNav: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: '#ffffff',
borderTopWidth: 1,
borderTopColor: '#d1fae5',
paddingVertical: 12,
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
},
navItem: {
alignItems: 'center',
flex: 1,
},
activeNavItem: {
paddingTop: 4,
borderTopWidth: 2,
borderTopColor: '#059669',
},
navIcon: {
fontSize: 20,
color: '#94a3b8',
marginBottom: 4,
},
activeNavIcon: {
color: '#059669',
},
navText: {
fontSize: 12,
color: '#94a3b8',
},
activeNavText: {
color: '#059669',
fontWeight: '500',
},
});
export default LifeServiceApp;

打包
接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

最后运行效果图如下显示:

本文介绍了基于React Native和TypeScript开发跨平台生活服务助手应用的技术方案。项目采用函数式组件架构,核心功能包括服务展示、详情查看、预约管理等,适配iOS、Android和鸿蒙系统。通过严格定义Service类型确保数据一致性,使用Hooks进行状态管理,实现单向数据流。技术亮点包括:模块化设计分离业务逻辑,Base64图标优化性能,Flexbox实现响应式布局,以及完善的用户交互流程。文章还探讨了鸿蒙系统的适配策略和性能优化建议,并展望了引入AI推荐、实时数据同步等未来发展方向,为跨平台本地生活服务应用开发提供了实践参考。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
更多推荐




所有评论(0)