1. 为什么我会在 0 基础时直接选 React Native 做鸿蒙开发
先交代一下背景:我是从 Android 原生转到跨平台方向的,之前完全没写过 React Native,也没正经接触过鸿蒙应用开发。之所以敢直接上手“React Native 鸿蒙跨平台开发”这个方向,是因为我盯上了两个刚需场景——一是 App 启动时白屏时间太长,二是团队需要一套代码同时覆盖 Android、iOS 和鸿蒙。
这里先解释一个关键认知:React Native 能跑在鸿蒙上,并不是华为官方直接内置了 RN 支持,而是因为开源社区和厂商合作推动的 React Native for OpenHarmony 适配层。也就是说,你写的 JS 业务逻辑可以跨平台复用,但最终要落到鸿蒙的 ArkUI 组件树上,中间需要一套桥接实现。这个适配层目前已经能覆盖大部分核心组件和 API,但对于新手来说,最直观的感受就是:启动白屏的问题比纯 WebView 方案轻得多,又比纯原生开发省人力。
我踩过的第一个坑就是以为“React Native 鸿蒙开发”和普通 RN 开发完全一样,实际上编译目标、依赖版本、原生工程结构都需要按鸿蒙的规则来。如果你也是 0 基础,我强烈建议先理解清楚这条技术链:JS 代码 → RN 运行时 → 鸿蒙桥接层 → ArkUI 渲染。骨架屏 Skeleton 刚好是切入这个链路的最佳练习项目,因为它在业务上不复杂,但能逼你把 RN 组件如何映射到鸿蒙、样式如何生效、加载态如何管理都摸一遍。
适合看这篇文章的人,我觉得有三类:
- 完全没接触过 RN 和鸿蒙开发,但想快速跑通一个跨平台 Demo 的新手;
- 已经有 RN 开发经验,想迁移到鸿蒙平台,同时优化启动体验的开发者;
- 团队正在评估跨平台方案,想知道骨架屏这类 UI 细节在鸿蒙上能不能落地的人。
说白了,本文不是把官方文档念一遍,而是把我从环境搭建到骨架屏实现、再到鸿蒙适配踩坑的完整过程写出来,让你能少走弯路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与 React Native 鸿蒙工程初始化
2.1 你需要装哪些东西
别一上来就盯着鸿蒙 DevEco Studio 猛装,先把 RN 侧的环境搞定。我实际用到的环境版本如下,不同版本坑的位置不一样,建议尽量对齐:
- Node.js:18 或 20 LTS 版本,我用的 20.11.1,太老的版本会导致新版 RN CLI 跑不起来;
- JDK:17,鸿蒙工程编译对 JDK 版本有要求,11 或 8 都可能报 Gradle 兼容问题;
- DevEco Studio:5.0 及以上版本,用来打开鸿蒙原生工程;
- React Native:0.72 或 0.73 版本,目前鸿蒙适配层对这两个版本支持最好;
- OpenHarmony SDK:建议用 API 10 或更高版本,太低的话部分 RN 组件映射不了。
还有一个容易被忽略的点:你需要装好 HarmonyOS/OpenHarmony 的命令行工具,并确认 hdc 命令可用,否则后面连接模拟器或真机调试会卡住。我一开始就漏了 hdc,导致跑 react-native run-harmony 的时候一直提示找不到设备。
2.2 初始化 RN 工程并接入鸿蒙适配层
直接按普通 RN 方式初始化项目:
bash复制npx react-native init RnHarmonySkeleton --version 0.73.2
这一条命令会生成一个标准的 RN 工程。接下来要接入鸿蒙适配层,目前国内社区主要用的是 React Native for OpenHarmony 的镜像和脚手架。以我用的方案为例,你需要把鸿蒙工程目录生成到 harmony 文件夹下,然后在 harmony 目录里执行鸿蒙侧的依赖安装。
这里我不建议新手直接手动改原生工程,因为 ArkTS 和 ArkUI 的工程结构对没接触过的人来说会非常绕。更稳的方式是使用社区提供的初始化脚本,它会自动完成以下工作:
- 在
harmony目录生成 OpenHarmony 工程; - 配置好 RN 依赖的
react_native_openharmony包; - 把 RN 的 bundle 加载逻辑接入 ArkUI 的
RNInstance生命周期。
等脚本跑完,整个工程会同时包含 android、ios 和 harmony 三个目录。看到 harmony 目录出现时,说明工程已经具备跨三个平台的结构了。
2.3 鸿蒙侧 dev 模式的启动流程
很多新手以为鸿蒙跟 Android 一样,直接 npm start 就能跑起来,实际上鸿蒙侧的加载流程要稍微绕一下。你需要先在 DevEco Studio 里打开 harmony 目录,等 Gradle 同步完成,然后连接鸿蒙模拟器或真机。启动 Metro 服务:
bash复制npm start
然后在 DevEco Studio 里点击运行,App 会启动并尝试从 Metro 拉取 JS bundle。如果一切正常,你会看到骨架屏和业务界面都能正常渲染。
我遇到的一个高频报错是 bundle 加载超时,这是因为鸿蒙模拟器默认网络环境和 Metro 的访问地址没配好。解决办法是在 DevEco Studio 的运行配置里,把 Metro 地址改成你电脑的局域网 IP,而不是默认的 localhost。这个坑在后文常见问题里会展开讲。
3. 骨架屏 Skeleton 在 React Native 中的实现思路
3.1 为什么骨架屏能解决白屏问题
原生 RN 应用在启动时,需要经历“加载 JS Bundle → 解析并执行 JS → 渲染原生组件”这几个阶段。如果 bundle 体积大或设备性能一般,用户会看到一段没有内容的纯白屏,体验非常糟糕。骨架屏的本质是先渲染一个与最终界面布局一致的灰色占位块,让用户感知到“内容马上就来”,而不是“应用卡死了”。
用生活化的方式理解:你去餐厅点餐,服务员先给你一张空盘子摆上餐具,而不是让你干等十分钟看桌面。骨架屏就是这张空盘子,它不代替真正的菜,但能极大降低等待焦虑。
在 RN 中,骨架屏通常可以用三种方式实现:
- 手动写占位 View,加背景色和圆角,配合动画模拟加载;
- 使用第三方库,如
react-native-skeleton-placeholder; - 在鸿蒙侧用原生组件实现骨架屏,再通过桥接暴露给 JS 调用。
对于 0 基础的新手,我建议你先把第一种方式吃透,因为它能帮你理解 RN 的布局和动画机制。后面如果团队需要统一的设计规范,再引入第三方库也不迟。
3.2 手动实现一个基础的 Skeleton 组件
在 App.tsx 里写一个最简单的骨架屏组件,核心思路是用 Animated 配合透明度循环产生呼吸灯效果。示例代码如下:
tsx复制import React, { useEffect, useRef } from 'react';
import {
View,
Text,
StyleSheet,
Animated,
Easing,
} from 'react-native';
const SkeletonBlock = ({ width, height, style }) => {
const opacity = useRef(new Animated.Value(0.4)).current;
useEffect(() => {
const animation = Animated.loop(
Animated.sequence([
Animated.timing(opacity, {
toValue: 1,
duration: 700,
easing: Easing.inOut(Easing.ease),
useNativeDriver: true,
}),
Animated.timing(opacity, {
toValue: 0.4,
duration: 700,
easing: Easing.inOut(Easing.ease),
useNativeDriver: true,
}),
])
);
animation.start();
return () => animation.stop();
}, [opacity]);
return (
<Animated.View
style={[
{
width: width || '100%',
height: height || 20,
borderRadius: 8,
backgroundColor: '#E8E8E8',
opacity,
},
style,
]}
/>
);
};
const SkeletonHome = () => {
return (
<View style={styles.container}>
<View style={styles.header}>
<SkeletonBlock width={80} height={80} style={styles.avatar} />
<SkeletonBlock width={200} height={20} style={{ marginLeft: 12 }} />
</View>
<SkeletonBlock height={180} style={{ marginTop: 16 }} />
<View style={styles.row}>
<SkeletonBlock width="30%" height={60} />
<SkeletonBlock width="30%" height={60} />
<SkeletonBlock width="30%" height={60} />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, backgroundColor: '#fff' },
header: { flexDirection: 'row', alignItems: 'center' },
avatar: { borderRadius: 40 },
row: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 16,
},
});
export default SkeletonHome;
这段代码的核心就是在 SkeletonBlock 组件里封装了一个透明度变化动画。useNativeDriver: true 表示动画在原生侧驱动,性能更好,但要注意透明度动画是支持原生驱动的,所以这里可以放心用。
3.3 如何把 Skeleton 变成可复用的业务组件
如果只写一个页面级骨架屏,那复用的价值不大。实际项目中,我建议把骨架屏设计成与业务数据模型一一对应的结构。比如你的首页有头像区、轮播区、列表区,那就定义一个 HomeSkeletonProps,按数据区块渲染不同的占位块。
这里的经验是:骨架屏不是越像最终页面越好,而是要做到“足够识别但不抢眼”。如果做得太精细,反而会在网络回包后产生明显的跳动感。灰色块之间要留出合理的间距,模拟真实内容的呼吸感。
我在重构时,把骨架屏分成三层:
- 基础原子组件:
SkeletonBlock,负责单个占位块; - 组合区块:
SkeletonList、SkeletonCard、SkeletonProfile,对应业务常见模块; - 页面级骨架屏:
HomeSkeleton、ProfileSkeleton,直接引用于路由加载处。
这样做的好处是,业务方可以像搭积木一样拼出不同页面的加载态,而不是每做一个页面就重新写一套骨架屏。
4. 骨架屏在鸿蒙侧的适配与渲染差异
4.1 React Native 组件如何映射到鸿蒙 ArkUI
很多新手会下意识认为 React Native 的跨平台能力是直接把 JS 翻译成原生代码,实际上不是。RN 的组件在鸿蒙上是通过桥接层映射到 ArkUI 组件的,例如 JS 里的 View 会映射为 Column 或 Row,Text 会映射为 Text 组件,Animated.View 则对应鸿蒙侧的动画容器。
理解了这层映射关系,你就能明白为什么有些样式属性在 Android 上正常、在鸿蒙上却不生效。比如阴影属性,RN 里常用的 shadowColor、shadowOpacity 在鸿蒙上的实现可能被转换为 boxShadow,支持程度和表现会略有差异。骨架屏里我大量使用了 borderRadius 和 opacity,这两个属性在鸿蒙适配层上支持得比较稳定,所以整体踩坑不多。
4.2 骨架屏在鸿蒙模拟器上的性能表现
我一开始担心鸿蒙侧 JS 引擎执行动画会不会卡顿,毕竟 ArkUI 自带的动画是声明式的,而 RN 的动画是命令式的,两者经过桥接后会不会有性能损耗?实测下来,在 API 10 模拟器上,Animated.loop 的透明度动画能稳定在 60 帧左右,几乎是流畅的。
原因在于,RN for OpenHarmony 对 Animated 模块做了优化,像透明度、位移、缩放这类常见动画属性,会走原生动画驱动,而不是每帧回传 JS 计算。所以你的骨架屏动画可以放心大胆写,不需要刻意降级为静态占位图。
不过有一个限制要提一下:Easing 的复杂曲线在鸿蒙上的表现不一定和 Android 完全一致,尤其是 bounce 这类回弹效果。骨架屏如果希望保持全平台视觉一致,建议只使用 Linear、Ease、EaseIn、EaseOut 这类标准曲线。
4.3 避免把骨架屏做成“二次闪烁”
鸿蒙应用启动时,往往会先加载一张系统启动图,再进入 React Native 容器。如果你只在 RN 内部实现骨架屏,那么从启动图到骨架屏之间仍有一段空白。要彻底解决这个问题,需要把骨架屏的内容同步放到鸿蒙原生层,作为启动图的延伸。
操作方案是:在 DevEco Studio 里找到 EntryAbility 的加载逻辑,在 RN 根视图挂载前,先用 ArkUI 渲染一个和 JS 侧布局一致的静态骨架屏,等 RNInstance 加载完成后再切换。这里的常规经验是,JS 侧骨架屏和原生侧骨架屏不必完全一样,原生侧只需要保留一个品牌色块或大致布局即可,避免过度开发。
我第二次重构时就踩了“二次闪烁”的坑:原生启动图是大红色块,RN 骨架屏却是浅灰色,用户会感觉页面闪了两下。后来我把原生启动图也改成浅灰,并把骨架屏的背景统一为白色,整体过渡平滑了很多。
5. 从 0 到 1 的完整实操过程记录
5.1 基础工程跑通的完整命令序列
为了让你能顺利复现,我把关键命令按顺序贴在下面。注意,这只是我实测可行的顺序,不同环境下你可能需要根据报错做微调。
bash复制# 1. 创建 RN 工程
npx react-native init RnHarmonySkeleton --version 0.73.2
# 2. 进入工程目录
cd RnHarmonySkeleton
# 3. 安装鸿蒙适配依赖(具体包名以你使用的适配仓库为准)
npm install react-native-openharmony
# 4. 生成鸿蒙工程目录(这里使用社区脚手架命令,按你实际工具调整)
npx rnoh --platform harmony
# 5. 启动 Metro
npm start
# 6. 打开 DevEco Studio,加载 harmony 目录,等待同步完成后运行
如果第四步的脚手架命令不一样,请直接参考你当前使用的适配仓库文档。不同版本的工具链生成的工程结构会有些许差异,但整体思路不变。
5.2 实现加载态切换的核心逻辑
骨架屏要真正发挥作用,还差一步:让它与数据请求状态联动。我写了一个简单的 useSkeleton Hook,用来模拟数据加载完成后再隐藏骨架屏:
tsx复制import { useState, useEffect } from 'react';
const useSkeleton = (delay = 1500) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => setLoading(false), delay);
return () => clearTimeout(timer);
}, [delay]);
return loading;
};
export default useSkeleton;
然后在页面中使用:
tsx复制const HomeScreen = () => {
const loading = useSkeleton(2000);
if (loading) {
return <SkeletonHome />;
}
return (
<View>
<Text>首页内容加载完成</Text>
</View>
);
};
这里的 loading 状态也可以替换为真实的请求状态,例如接口返回后再置为 false。核心思想是:骨架屏不是独立存在的动画,而是加载状态的可视化呈现。
5.3 在鸿蒙模拟器上真机运行的完整流程
实际操作时,我建议按这个顺序来,能省很多时间:
- 先启动 Metro,并确认终端输出
Loading dependency graph正常; - 再启动鸿蒙模拟器,确保模拟器和电脑处于同一网络;
- 在 DevEco Studio 中修改 Metro host 地址为你电脑的局域网 IP;
- 点击运行,观察 DevEco 的日志输出,确认 bundle 是否加载成功;
- 成功进入首页后,再切换网络状态或延迟接口,验证骨架屏显示。
我踩过的一个典型问题:如果用默认的 localhost,鸿蒙模拟器里会加载不到 bundle,因为模拟器里的 localhost 指向的是模拟器自身,不是你的电脑。解决办法就是把 host 改成局域网 IP。
5.4 骨架屏与真机状态栏的适配
鸿蒙手机普遍有挖孔屏或胶囊挖孔,如果骨架屏布局没有考虑状态栏避让,头部占位块可能会顶到系统状态栏下面。通常 RNN 的 SafeAreaView 在鸿蒙上也有对应处理,但实测下来,部分机型需要手动设置 paddingTop。
我给出的建议是:在骨架屏头部区域预留一个 StatusBar.currentHeight 的高度,而不是把所有内容都交给安全区自动处理。因为骨架屏的布局越贴近真实页面,避让逻辑就越重要。
6. 工具选型与方案对比
6.1 为什么不直接用 WebView 加载骨架屏
有些团队会把网页版的骨架屏方案直接搬到 App 里,用一个 WebView 显示静态布局。这种方式在短期内实现成本低,但存在两个明显问题:一是 WebView 启动本身就有开销,在低端机上可能比 RN 的 bundle 加载还慢;二是骨架屏如果要做动画,WebView 里的 DOM 动画和原生动画的协调度差,容易出现掉帧。
RN 方案的明显优势是动画走原生驱动,骨架屏的“呼吸感”更均匀,同时因为不用启动完整的浏览器内核,整体内存占用也更低。对于鸿蒙这类对资源开销比较敏感的平台,RN 方案更值得尝试。
6.2 Skeleton 组件库 vs 手写组件
我在项目里体验过 react-native-skeleton-placeholder,它在 Android 和 iOS 上表现稳定,但在鸿蒙适配层并非所有底层依赖都被支持。如果你只是做一个简单骨架屏,我建议手写,因为代码量其实很小;如果你要覆盖大量页面,且团队多人协作,再引入组件库,因为这能保证视觉一致性。
一个折中方案是:手写核心骨架屏组件,但把样式和区块结构做成配置化,后续如果团队决定换组件库,只需要把底层渲染方式替换掉,业务侧不用大改。
6.3 ArkUI 原生骨架屏 vs RN 骨架屏
如果你的项目是纯鸿蒙应用,不涉及多平台,那直接用 ArkUI 的 CustomDialog 或自定义组件做骨架屏会更轻量。但如果你的目标本来就是跨平台,那就没必要在鸿蒙侧单独重新实现一套,因为维护成本会翻倍。
在这里我的个人经验是:跨平台项目的 UI 细节必须坚持“以低端平台的能力为准”的原则。也就是说,骨架屏的样式和动画复杂度,应以鸿蒙适配层的支持程度为上限,而不是以 Android 或 iOS 的能力为上限,否则最后为了修复鸿蒙上的细节问题,你会耗费大量精力。
7. 常见问题与排查技巧实录
7.1 bundle 加载超时或白屏
这是最典型的问题。如果你的应用启动后一直白屏,且 DevEco 日志里出现类似 bundle load timeout 的错误,排查思路按照这个顺序来:
- 确认 Metro 是否处于正常运行状态,终端有没有打印错误;
- 确认鸿蒙模拟器与电脑网络是否互通,可以用模拟器里的浏览器访问电脑的
http://局域网IP:8081/index.bundle试试; - 如果访问不了,检查防火墙是否拦截了 8081 端口;
- 确认 DevEco 的运行配置里 Metro host 是否已改为局域网 IP。
我遇到的最多情况是防火墙拦截,尤其是公司电脑,Windows 防火墙会默认拦掉 Node.js 的入站请求。解决办法是在防火墙允许列表里把 Node.js 加上,或者临时换用桥接网络。
7.2 透明动画在鸿蒙上不生效
如果你发现骨架屏静态显示了,但呼吸灯动画没有动,先检查 useNativeDriver 是否为 true。在部分鸿蒙版本中,过度复杂的动画参数会导致原生驱动初始化失败,但因为 RN 的报错可能不够明显,看起来就像是动画没生效。
解决办法是先把 useNativeDriver 改为 false 测试,如果动画恢复,说明是原生驱动兼容性问题。骨架屏这类轻量动画,即使使用 JS 驱动,性能影响也不大,可以接受。
7.3 组件在 Android 正常但鸿蒙样式错位
遇到这种情况,优先检查是否使用了鸿蒙适配层不支持的样式属性。常见的坑包括:
position: absolute配合某些top/left计算在鸿蒙上偏移;- 某些
shadow属性在鸿蒙上表现为外发光或直接不显示; elevation属性在鸿蒙上不支持,需要使用其他方式模拟层级。
骨架屏里最容易踩的是圆角问题:如果父容器设置了 overflow: 'hidden',在鸿蒙上嵌套的圆角子组件可能会被裁剪掉一部分。解决思路是把圆角样式放在最外层容器上,或者对子组件单独设置与父容器相同的圆角。
7.4 真机调试与模拟器表现不一致
鸿蒙真机和模拟器在动画帧率、字体渲染、滚动表现上存在细微差异。骨架屏这类静态布局差异不大,但如果你的骨架屏带有图片占位、动态渐变等复杂效果,一定要在真机上做一次回归测试。
我建议把骨架屏动画的时长控制在“视觉可感知但不过度拖沓”的区间,一般是 800ms 到 1200ms 一个循环。过短的动画会让用户觉得界面闪烁,过长的动画则让用户怀疑应用卡住。在我实际使用中,1000ms 的循环时长比较均衡。
8. 启动体验优化中的另类技巧
8.1 用资源配置降低白屏感
除了骨架屏,你还可以在鸿蒙原生侧把首屏需要的静态资源提前打包进应用,避免在加载 bundle 的过程中发起网络图片请求。骨架屏本身不依赖网络图片,所以它能作为第一时间呈现的界面,但后续真实内容的图片加载同样会影响体验。
这里的思路是:把首页最重要的 1~2 张图片资源在原生工程里做本地打包,等 RN 加载完成后直接引用本地资源路径。这样即使网络慢,用户也不会看到图片位置的空白。
8.2 缩小 bundle 体积,让骨架屏尽早出现
骨架屏再怎么优化,也必须在 RN 环境启动后才能渲染。如果你能缩小 JS bundle 体积,就能让骨架屏提前出现。常见的优化手段包括:
- 使用 Metro 的
transform配置移除不必要的 console 输出; - 使用按需加载,首页只打包必要业务代码;
- 把第三方库中体积大的组件改成原生模块或延迟加载。
我实测过,一个首页 bundle 从 1.8MB 压缩到 1.2MB 后,启动时间能减少约 20%。在低端机上,这个提升非常明显。
8.3 骨架屏的降级方案
并不是所有用户都需要骨架屏。如果用户设备处于低电量模式或系统开启了省电模式,你可以考虑直接使用静态纯色占位,避免动画带来的额外电量消耗。虽然动画开销很小,但这种细节优化会显得你的应用更贴近系统体验。
在 RN 侧,可以通过 NativeModules 获取鸿蒙的系统状态,例如电量或省电模式,然后决定是否禁用动画。不过这个能力在不同适配层上的支持程度不一样,建议先做成可配置开关,再逐步接入系统状态。
9. 跨平台项目里 Skeleton 的工程化设计
9.1 从页面级骨架屏走向组件级骨架屏
如果团队项目规模变大,单纯在页面里写骨架屏代码会导致大量重复。我的做法是建立一套骨架屏的“设计令牌”,比如统一的背景色、占位块圆角、动画时长、间距规则,然后把这些令牌作为常量维护在一个文件中。
例如:
typescript复制export const SKELETON_TOKENS = {
backgroundColor: '#E8E8E8',
highlightColor: '#F2F2F2',
borderRadius: 8,
animationDuration: 800,
};
所有骨架屏组件只引用这份常量,后续改设计规范时只需要改一处。
9.2 让骨架屏与数据接口联动
骨架屏不能一直转圈等接口,也不能在接口返回数据后立即消失,导致界面跳动。比较理想的做法是给骨架屏一个最小展示时间,例如 400ms,确保用户能感知到页面已经切换,而不是一闪而过。
另一种做法是使用“延迟隐藏”机制:接口返回数据后,等待当前动画循环走完一个完整周期再隐藏骨架屏。在 RN 中可以用 Animated 的回调来实现。这里我只提供思路,因为不同团队的交互规范不同,你需要按业务特性调整。
9.3 骨架屏的测试与验收标准
我建议把骨架屏列为前端质量验收的一部分,用三个指标来衡量是否合格:
- 骨架屏是否在启动后 300ms 内出现;
- 骨架屏与真实内容切换时是否无明显跳动;
- 骨架屏形态是否覆盖页面主体模块。
这三个指标都可以通过简单的录屏回放来检查,不需要复杂工具。如果你有自动化测试环境,还可以对骨架屏的出现和消失时机做断言。
10. 踩坑心得:0 基础做 RN 鸿蒙开发的三个建议
最后分享一点个人体会,不唱高调,都是实际项目里砸过时间才换来的。
第一,环境问题比代码问题更容易劝退新手。我前三天几乎都在和 DevEco Studio、Gradle、Node 版本、hdc 工具链作斗争,真正写 React Native 代码的时间不足半天。如果你也是 0 基础,请先做好心理建设,务必按本文的环境版本对齐,不要盲目升级最新版,因为最新版往往意味着适配层还没跟上。
第二,骨架屏这种“小功能”是理解跨平台渲染原理的绝佳入口。通过它,你能清楚知道 JS 组件如何映射到鸿蒙 ArkUI,样式属性如何被解析,动画如何走原生驱动。掌握了这套逻辑,后面做复杂的业务功能会顺畅很多。
第三,不要把鸿蒙当成“Android 的复制品”,也别因为鸿蒙生态年轻就轻视它。实际体验下来,RN for OpenHarmony 的适配层已经能处理大部分常规 UI 需求,但细节上确实有差异。做跨平台项目,心态上要接受“同一套代码在不同平台上表现不完全一致”,关键是提前做好视觉和交互差异的预案。
如果你打算入坑,我建议先单独拉一个分支,只做首页骨架屏,把从 Metro 到 DevEco、从 JS 到 ArkUI 的整条链路跑通,再考虑逻辑扩展。这样即使遇到问题,排查范围也足够小。
