Taro 鸿蒙技术黑幕系列(一):怎样将 React 代码跑在 ArkUI 上 ...

打印 上一主题 下一主题

主题 815|帖子 815|积分 2445

<blockquote id="w-e-element-15">  基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章将深入解析 Taro 怎样实现使用 React 开辟高性能鸿蒙应用的技术黑幕  背景

随着鸿蒙操作系统的快速发展,开辟者们期待将现有跨平台应用迁徙到鸿蒙平台。Taro作为一个盛行的跨平台开辟框架,其支持鸿蒙系统的大概性引起了广泛关注。
然而,鸿蒙系统采取全新的ArkUI框架作为原生UI开辟方案,与Taro本来支持的平台存在显着差别。将Taro的React开辟模式与ArkUI的声明式UI开辟范式举行有用对接成为了一个技术难题。
本文将探讨Taro框架怎样通过创新方案实现React代码在ArkUI上的运行。我们将解析Taro的运行时原理,剖析其怎样将React组件转换为ArkUI可辨认的结构,以及相关技术寻衅和解决方案。
Taro运行时原理先容

为了理解Taro适配ArkUI的核心机制,我们起首需要深入相识Taro的运行时原理。Taro通过巧妙的设计,将React代码转换为各平台可执行的形式,其中包括对鸿蒙平台的适配。下面将详细先容 Taro 是怎样将 React 代码转换为ArkUI可执行的形式,以及节点转换的流程细节。




1. 从 React 到 Taro

React 跨平台的秘诀

在 Taro 的运行时中,起首执行的是开辟者编写的 React 业务代码。这些代码定义了业务应用的结构、逻辑和状态管理。那么既然要对接React,那肯定先得相识它的核心架构,React是怎么运作的:





相识了React的基本架构后,我们可以清晰地看到,Renderer 作为渲染器,负责将React的虚拟节点操作终极映射到相应的平台上。例如,react-dom将这些操尴尬刁难接到浏览器上,而react-native则将其对接到iOS或Android平台。这种设计使得React可以或许适配不同的运行环境。




正是基于这种思绪,Taro 团队设计了 Taro Renderer。这个渲染器充当了 React 与 Taro 虚拟节点树之间的桥梁,使得 React 的操作可以被转换为 Taro 的中心表示。
通过实现 Taro Renderer 天生 Taro 虚拟节点树





HostConfig接口实现

要实现 Taro 的 Renderer,我们需要实现 React Reconciler 所需的 hostConfig 接口。这个接口定义了一系列方法,用于创建、更新和管理渲染目标平台的元素。以下是一些关键的 hostConfig 方法:
createElement:创建ArkUI对应的元素。
createTextInstance:创建文本节点。
appendChild:将子元素添加到父元素。
removeChild:从父元素中移除子元素。
insertBefore:在指定位置插入元素。
commitUpdate:更新元素属性。
通过实现这些方法,Taro Renderer 可以或许将 React 的操作转换为 Taro 虚拟节点树的相应操作。这个虚拟节点树是 Taro 实现跨平台的核心,它为不同平台的渲染提供了统一的中心表示。
  1. // 部分HostConfig接口实现的代码
  2. const hostConfig: HostConfig {
  3.     // 创建Taro虚拟节点
  4.   createInstance (type, props: Props, _rootContainerInstance, _hostContext, internalInstanceHandle: Fiber) {
  5.     const element: TaroElement = TaroNativeModule.createTaroNode(type)
  6.     precacheFiberNode(internalInstanceHandle, element)
  7.     updateFiberProps(element, props)
  8.     return element
  9.   },
  10.   // 更新属性
  11.     commitUpdate (dom, updatePayload, _, oldProps, newProps) {
  12.       updatePropsByPayload(dom, oldProps, updatePayload)
  13.       updateFiberProps(dom, newProps)
  14.     },
  15.     // 插入节点
  16.     insertBefore (parent: TaroElement, child: TaroElement, refChild: TaroElement) {
  17.       parent.insertBefore(child, refChild)
  18.     },
  19.     // 移除节点
  20.     removeChild (parent: TaroElement, child TaroElement) {
  21.       parent.removeChild(child)
  22.     },
  23.     // ...
  24. }
复制代码
2. 从 Taro 到 ArkUI

在将 Taro 虚拟节点树转换为 ArkUI 的过程中,我们需要举行几个关键步骤:





Taro Element转换 ArkUI过程
起首,我们需要在 ArkUI 层面实现一套与 Taro 组件对应的组件库。这个步骤至关重要,因为它建立了 Taro 组件和 ArkUI 组件之间的映射关系。例如,我们需要为 Taro 的 View、Text、Image 等基础组件创建对应的 ArkUI 组件。这样,当我们遍历 Taro 虚拟节点树时,就能找到每个节点在 ArkUI 中的对应实现。

在节点映射的过程中,我们注意到 Taro 虚拟节点树与实际 ArkUI 视图结构存在差别。这些差别主要体现在以下几个方面:
复合组件结构:某些 Taro 组件在 ArkUI 中大概需要多个组件配合实现。例如,ScrollView 组件在 ArkUI 中大概需要一个 Scroll 节点搭配一个 Stack 来实现完备功能。
层级位置调整:一些特殊定位的节点(如 Fixed 定位的元素)在终极渲染时的位置大概与其在虚拟节点树中的层级不同等。这需要在天生渲染树时举行特殊处理。
平台特定组件:某些 Taro 组件大概需要使用 ArkUI 特有的组件或结构方式来实现,这要求我们在转换过程中举行适当的调整和映射。




因此,在天生渲染树时,我们需要一个更复杂的转换过程,不但要思量简朴的一对一映射,还要处理这些结构性的差别,确保终极天生的 ArkUI 组件树可以或许正确反映预期的视图结构和结构。因此,在Taro > ArkUI的节点对接中,我们需要维护一棵 Render Tree,用于做中心的桥梁。

1. 根据组件范例 创建 Taro Element

在创建 Taro Element 的过程中,我们根据组件的范例来实例化相应的 Taro 元素。这一步骤是将 React 组件转换为 Taro 内部表示的关键。
  1. // 根据组件类型创建对应的Taro节点
  2. std::shared_ptr<TaroElement> TaroDocument::CreateElement(napi_value &node) {
  3.         // 获取组件类型
  4.     TAG_NAME tag_name_ = TaroDOM::TaroElement::GetTagName(node);
  5.     // 根据组件类型,创建对应的实例
  6.     std::shared_ptr<TaroDOM::TaroElement> item;
  7.     switch (tag_name_) {
  8.         case TAG_NAME::SCROLL_VIEW: {
  9.             item = std::make_shared<TaroDOM::TaroScrollView>(node);
  10.             break;
  11.         }
  12.         case TAG_NAME::IMAGE:
  13.             item = std::make_shared<TaroDOM::TaroImage>(node);
  14.             break;
  15.         }
  16.         case TAG_NAME::SPAN:
  17.         case TAG_NAME::TEXT: {
  18.             item = std::make_shared<TaroDOM::TaroText>(node);
  19.             break;
  20.         }
  21.         case TAG_NAME::SWIPER: {
  22.             item = std::make_shared<TaroDOM::TaroSwiper>(node);
  23.             break;
  24.         }
  25.         // ...
  26.     }
  27.     return item;
  28. }
复制代码
2. Taro Element 创建 Taro RenderNode

在创建完 Taro Element 之后,下一步是将其转换为 Taro RenderNode。这个过程是将 Taro 的内部表示进一步转化为更靠近 ArkUI 结构的渲染节点。
  1. // 创建 Taro RenderNode
  2. void TaroSwiper::Build() {
  3.     if (!is_init_) {
  4.         // create render node
  5.         TaroElementRef element = std::static_pointer_cast<TaroElement>(shared_from_this());
  6.         auto render_swiper = std::make_shared<TaroSwiperNode>(element);
  7.         render_swiper->Build();
  8.     }
  9. }
复制代码
3. Taro RenderNode 创建 ArkUI Node

末了一步是将 Taro RenderNode 转换为实际的 ArkUI 节点。这个过程涉及到直接与 ArkUI 的底层 API 交互,创建和配置 ArkUI 的原生节点。实现了从 Taro 的渲染节点到 ArkUI 实际可渲染节点的终极转换。
  1. // 创建 ArkUI Node
  2. void TaroSwiperNode::Build() {
  3.     NativeNodeApi *nativeNodeApi = NativeNodeApi::getInstance();
  4.     // 创建一个Swiper的ArkUI节点
  5.     SetArkUINodeHandle(nativeNodeApi->createNode(ARKUI_NODE_SWIPER));
  6. }
复制代码
通过这三个步骤,我们在 C++ 层面成功实现了 React 组件结构到 ArkUI 原生组件结构的映射。这一过程使 Taro 应用可以或许在鸿蒙系统上准确地渲染和运行,为跨平台开辟提供了有力支持。
总结

末了总结下,本文探讨了Taro框架怎样将React代码成功运行在鸿蒙系统的ArkUI上。这个过程主要分为两个关键部门:




React > ArkUI 架构图
1. Taro对接React

Taro通过实现自定义的Renderer来对接React。这个Renderer包含了一系列方法,如createInstance、commitUpdate等,用于将React的操作转换为Taro虚拟节点树的操作。这个虚拟节点树是Taro实现跨平台的核心,为不同平台的渲染提供了统一的中心表示。
2. Taro对接ArkUI

Taro通过自定义Renderer将React操作转换为虚拟节点树,然后通过三步转换过程将其映射到ArkUI结构。这个过程涉及Taro Element、Taro RenderNode和ArkUI Node这三棵树的维护,主要通过这三个流程步骤实现:
1.创建Taro Element:这一步将React组件转换为Taro内部表示。
2.创建Taro RenderNode:将Taro的内部表示进一步转化为更靠近ArkUI层级结构的渲染节点。
3.创建ArkUI Node:末了一步是将Taro RenderNode转换为实际的ArkUI节点,直接与ArkUI的底层API交互。
通过这种方式,Taro成功地将React组件结构映射到ArkUI原生组件结构,使得Taro应用可以或许在鸿蒙系统上准确地渲染和运行,同时也为跨平台开辟提供了有力支持。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表