尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

@tarojs/router 源码解析:Taro H5 端兼容小程序规范的路由系统

@tarojs/router 源码解析:Taro H5 端兼容小程序规范的路由系统 tarojs/router 源码解析Taro H5 端兼容小程序规范的路由系统【免费下载链接】taro开放式跨端跨框架解决方案支持使用 React/Vue 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。项目地址: https://gitcode.com/gh_mirrors/tar/tarotarojs/router是 Taro 仓库中负责 H5 端路由的核心包位于 packages/taro-router它把小程序的路由与页面栈规范navigateTo、switchTab、getCurrentPages、页面onShow/onHide/onUnload生命周期等完整复刻到浏览器环境。本文以该包的官方 README 为主线逐项拆解createRouter核心 API 的每个参数并结合仓库源码说明路由模式、自定义路由映射、导航 API 与页面栈的底层实现帮助读者理解 Taro 编译到 H5 后“小程序式路由”是如何运转的。一、包定位H5 端路由系统根据 packages/taro-router/README.md 的定义tarojs/router是H5 端路由系统。它并不直接面向开发者书写业务代码而是被编译链路中的tarojs/taro-loader/h5调用在应用入口文件中调用其核心 API创建一个兼容小程序路由规范的应用——也就是说在 H5 上运行时页面跳转、生命周期、TabBar 切换、页面栈等行为都尽量与小程序端保持一致从而让一套 Taro 代码在两端获得一致的路由体验。从包结构看其职责被划分为清晰的几个模块packages/taro-router/srcrouter/spa.ts/router/mpa.ts单页SPA与多页MPA两种路由入口router/page.ts/router/stack.ts页面实例的加载、卸载、显隐管理与页面栈router/navigation-bar.ts/tabbar.ts/navigationBar.ts导航栏与 TabBar 的 DOM 渲染history.ts基于history5封装 hash / browser / multi 三种历史模式api.ts实现navigateTo、navigateBack、switchTab、redirectTo、reLaunch、getCurrentPages等路由 APIevents/页面滚动与尺寸变化事件的绑定。该包的依赖见 packages/taro-router/package.json也很能说明问题history路由历史、universal-router路由解析与页面级代码分割、query-string路由 query 解析、mobile-detect与dingtalk-jsapi钉钉内页导航栏标题设置等。二、核心 APIcreateRouter 及其参数详解README 明确给出的核心 API 是createRouter(app, config, type, framework, reactDOM)暴露给tarojs/taro-loader/h5调用在应用入口文件中调用创建一个兼容小程序路由规范的应用。以下逐一说明各参数语义并结合源码给出它们的实际去向。1.app入口文件默认导出的组件app是应用入口文件默认app.js/app.ts的默认导出组件。在 H5 编译产物中它就是整个应用的根组件。从 loader 生成的代码看packages/taro-loader/src/h5.tsimport component from .../app // 入口文件默认导出 var inst creator(component, frameworkArgs) // 根据框架创建应用实例 var history historyCreator({ window }) handleAppMount(config, history) createRouter(history, inst, config, frameworkName)入口组件被creator随框架不同而变化React 为createReactApp、Vue 为createVueApp等包装成应用实例inst后连同路由配置一起交给createRouter。之后路由系统通过inst触发应用级生命周期。2.config应用全局配置及页面配置config是应用全局配置及页面配置对应app.config.js与page.config.js的返回内容。在 SPA 模式下它的类型为SpaRouterConfig定义见 packages/taro-router/types/router.d.tsexport interface SpaRouterConfig extends AppConfig { routes: Route[] // 编译期由 loader 生成的页面路由表每个 Route 含 path 与 load router: Router // 路由配置mode / basename / customRoutes / pathname / forcePath / enhanceAnimation PullDownRefresh?: any // 自定义下拉刷新组件 }其中routes由 packages/taro-loader/src/h5.ts 在编译期根据config.pages生成每个页面条目形如{ path: /pages/index/index, load: () import(...) }从而实现页面级代码分割window、tabBar等字段继承自AppConfig用于配置下拉刷新、导航栏样式、TabBar 列表等页面级的page.config.js配置如navigationStyle、enablePullDownRefresh、onReachBottomDistance则被打包进对应路由项在页面加载时读取。在createRouter内部packages/taro-router/src/router/spa.tsconfig首先被写入全局单例RouterConfig.config供页面判断、query 解析等后续逻辑随时读取。3.type框架类型type表示框架类型README 规定取值为react|vue|solid|preact四选一。它主要影响两个环节下拉刷新组件的创建SPA 渲染流程中若页面开启了enablePullDownRefresh会调用hooks.call(createPullDownComponent, el, pathname, framework, ...)来包装页面组件见 packages/taro-router/src/router/spa.ts该 hook 由对应框架包注册框架相关的适配逻辑框架名会被透传给下游的运行时用于区分不同框架的组件包装方式。4.framework框架的 default import 对象framework是框架的 default import 对象即对应框架包的默认导出如 React 的React。在 loader 生成代码中对应options.loaderMeta.importFrameworkName与type一起被传入createRouter(history, inst, config, frameworkName)。它是框架适配层如taro-framework-react、taro-framework-vue3、taro-framework-solid与路由系统协作的桥梁。5.reactDOM可选react-dom 的 default import 对象reactDOM为可选参数README 中标注为react-dom的 default import 对象。它是为 React 系框架准备的额外渲染入口。需要说明的是以当前仓库源码为准packages/taro-router/src/router/spa.ts 中createRouter的实际签名为createRouter(history, app, config, framework?)历史版本中reactDOM相关的渲染职责在当前实现里已由tarojs/runtime的createPageConfig及框架 reconciler 承担因此 README 中的参数描述可视为对历史 API 语义的保留性说明。在编写基于本仓库的扩展代码时应以源码签名为准。三、入口链路loader 如何把这一切串起来理解createRouter的最佳入口是看编译产物。在 packages/taro-loader/src/h5.ts 中loader 会生成如下核心代码import { createRouter, createBrowserHistory, handleAppMount } from tarojs/router import component from .../app var config {...} // app.config router 配置 window.__taroAppConfig config config.routes [ // 页面路由表含按需加载 { path: /pages/index/index, load: () import(...) }, ... ] var inst creator(component, frameworkArgs) var history createBrowserHistory({ window }) // 依据 mode 选择 handleAppMount(config, history) // 挂载 #app 容器、初始化导航栏/TabBar createRouter(history, inst, config, frameworkName) // 启动路由 initPxTransform({ ... }) // 初始化 px 转换其中关键点history 按路由模式创建mode browser用createBrowserHistorymode multi用createMpaHistory其余默认用createHashHistory见 packages/taro-router/src/history.ts挂载助手二选一无 TabBar 时用handleAppMount仅注入taro_router容器并初始化导航栏有 TabBar 时用handleAppMountWithTabbar额外构建taro-tabbar__container结构并初始化 TabBar见 packages/taro-router/src/index.ts启动入口最终createRouter(history, inst, config, frameworkName)完成路由监听与首次页面渲染并触发app.onLaunch/app.onShow。四、路由模式与 Router 配置项README 虽未展开 Router 配置但config.router是createRouter的config参数中决定路由行为的关键子对象其完整定义见 packages/taro-router/types/router.d.tsexport interface Router { mode: IH5RouterConfig[mode] // hash | browser | multi basename: string // 基础路径如 /app/ customRoutes?: Recordstring, string | string[] // 自定义路由别名映射 pathname: string // 当前路径内部维护 forcePath?: string // 强制渲染指定路径 enhanceAnimation?: boolean // 增强路由动画可修复返回页面白屏 }各配置项的作用与实现modehash默认、browser、multi三种模式。前两者由history5的createHashHistory/createBrowserHistory实现multi则是包内自定义的MpaHistorypackages/taro-router/src/history.ts通过重写push/replace为整页跳转window.location.assign/replace并将popstate、自定义pushState/replaceState事件统一映射为PUSH/REPLACE/POP三种 action。basename应用部署在子路径时使用。SPA 路由会通过stripBasename/prependBasename在原始 URL 与内部路径之间换算见 packages/taro-router/src/router/page.ts 及 packages/taro-router/src/utils/navigate.ts 中的processNavigateUrl。customRoutes自定义路由映射允许为页面路径配置对外别名例如把/pages/index/index对外暴露为/实现“根目录直达首页”或短路径跳转。该映射在createRouter启动时注入routesAlias单例packages/taro-router/src/utils/index.ts支持一对一或一对多string | string[]。forcePath强制指定当前渲染路径用于开发调试等场景见 packages/taro-router/src/router/spa.ts。enhanceAnimation配合路由动画使用开启后可解决返回页面时白屏的问题源码注释提示其依赖:has()选择器部分浏览器不支持。五、导航 API 与页面栈的底层实现兼容小程序路由规范的另一半是导航 API 与页面栈。它们都由tarojs/router实现并通过tarojs/taro暴露给业务代码调用。1. 五个导航 API 的统一实现packages/taro-router/src/api.ts 中navigateTo、redirectTo、switchTab、reLaunch、navigateBack共享一个navigate内核URL 预处理processNavigateUrl依次处理相对路径./、../归一化、补齐/前缀、按customRoutes做别名映射routesAlias.getAlias、拼接basename动作映射navigateTo→history.pushredirectTo/switchTab→history.replacereLaunch→ 重置页面栈后再history.replacenavigateBack→history.go(-delta)并处理 delta 超出栈深度的边界packages/taro-router/src/api.ts回调与事件通道navigateTo成功后返回{ errMsg: navigateTo:ok, eventChannel }并把页面间通信的EventChannel暴露给业务方对应小程序events参数用法。2. getCurrentPages 与页面栈getCurrentPages()返回当前页面栈packages/taro-router/src/api.ts其数据来源于 packages/taro-router/src/router/stack.ts 维护的页面栈。值得注意两点多页面multi模式下源码会在非生产环境打印警告多页面路由模式不支持getCurrentPages栈中每个页面实例会额外产出route字段去除 query 的路径与小程序规范对齐。3. 页面生命周期驱动页面实例的加载、显隐由 packages/taro-router/src/router/page.ts 中的PageHandler驱动这是 H5 端模拟小程序生命周期的核心load推入页面栈触发onLoad→onShow处理 TabBar 页面 / 默认导航栏样式类名与路由动画show/hideonShow/onHide隐藏时通过taro_page_shade类遮蔽旧页面unloadonUnload支持按delta批量卸载对应navigateBack(2)等并配合动画延迟触发__taroPageOnShowAfterDestroyed事件页面容器通过.taro_page#${path}定位路径中特殊字符会被转义滚动事件与onReachBottomDistance、resize事件由 packages/taro-router/src/events 统一绑定。路由解析则借助universal-routercreateRouter将routes转换为 UniversalRouter 路由表router.resolve(routerPath)按需加载页面 chunk404 时触发app.onPageNotFound与__taroRouterNotFound事件见 packages/taro-router/src/router/spa.ts。六、SPA 与 MPA两条路由入口的分工README 只介绍了createRouter但tarojs/router同时支持多页面应用。mode: multi时loader 会改用createMultiRouterpackages/taro-router/src/router/mpa.ts其行为差异在源码注释中有明确说明packages/taro-router/src/router/mpa.ts每个页面作为独立 HTML 打开新开页面相当于重启应用因此launchParam.path直接取当前pageName需要额外配置路由映射根目录跳转、404 页面等不支持app.onPageNotFound事件、不支持路由动画TabBar 会多次加载getCurrentPages不可用应用级生命周期可能多次触发每次进入页面都会执行onLaunch/onShow。在 MPA 模式下页面标题通过监听__taroH5SetNavigationBarTitle事件实时更新document.title且针对钉钉内嵌浏览器会自动调用dingtalk-jsapi设置钉钉导航栏标题见 packages/taro-router/src/utils/navigate.ts 的setMpaTitle。七、小结从 README 到源码的完整链路以packages/taro-router/README.md为骨架可以看到tarojs/router的完整闭环编译期taro-loader/h5依据app.config.js/page.config.js生成routes路由表与router配置选择createRouterSPA或createMultiRouterMPA与对应的 history 工厂启动期createRouter(history, app, config, framework)完成配置注册、UniversalRouter 路由表构建、onLaunch触发与首次渲染并监听history变化运行期导航 APInavigateTo等驱动history变更 → 路由解析按需加载页面 →PageHandler维护页面栈并驱动onLoad/onShow/onHide/onUnload生命周期 → TabBar、导航栏、下拉刷新、路由动画协同工作。对于想要扩展 Taro H5 路由行为的开发者建议重点阅读 packages/taro-router/src/router/spa.ts、packages/taro-router/src/router/page.ts 与 packages/taro-router/src/api.ts 三个文件它们覆盖了路由渲染、生命周期与导航 API 三大核心机制配置层面的完整字段则以 packages/taro-router/types/router.d.ts 为权威参考。【免费下载链接】taro开放式跨端跨框架解决方案支持使用 React/Vue 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。项目地址: https://gitcode.com/gh_mirrors/tar/taro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表