多 NavigationStack 路由治理实战

引言

当 App 进入多 Tab、多模块阶段后,单一导航栈很容易演变成“跳转难维护、回退不可控”。
更实用的方式是:每个业务域维护独立路径,由全局路由器统一调度

为什么要做多栈

  • 跳转逻辑按业务分治,改动边界更清晰
  • 回退链路更可预测
  • 登录拦截、权限判断可统一下沉

路由结构示例

import SwiftUI

enum HomeRoute: Hashable {
    case detail(id: String)
}

enum ProfileRoute: Hashable {
    case settings
}

final class AppRouter: ObservableObject {
    @Published var homePath = NavigationPath()
    @Published var profilePath = NavigationPath()

    func navigateToHome(_ route: HomeRoute) {
        homePath.append(route)
    }

    func navigateToProfile(_ route: ProfileRoute) {
        profilePath.append(route)
    }

    func popHome() {
        guard !homePath.isEmpty else { return }
        homePath.removeLast()
    }
}

视图接入方式

struct HomeRootView: View {
    @EnvironmentObject var router: AppRouter

    var body: some View {
        NavigationStack(path: $router.homePath) {
            HomePage()
                .navigationDestination(for: HomeRoute.self) { route in
                    switch route {
                    case .detail(let id):
                        DetailPage(id: id)
                    }
                }
        }
    }
}

扩展点:统一拦截

你可以把登录判断放在 navigate 前置层:

  • 未登录:先跳登录页
  • 登录成功:恢复目标路由

这样业务页面就不用重复写 if login 判断。

多栈落地路线

第 1 步:先做路由协议,不急着改页面

protocol RouteType: Hashable {}

protocol RouterType: AnyObject {
    associatedtype Route: RouteType
    var path: NavigationPath { get set }
    func push(_ route: Route)
    func pop()
}

第 2 步:引入路由解析器(Resolver)

protocol RouteResolver {
    associatedtype Route: RouteType
    associatedtype Destination: View
    @ViewBuilder func resolve(_ route: Route) -> Destination
}

第 3 步:统一跨模块跳转入口

  • 业务层不直接访问其他模块的 NavigationPath
  • 统一通过路由器转发
  • 统一处理登录态、权限态

回退链路治理经验

多栈常见 bug 是“页面返回到了错误 Tab”。
解决思路:

  • 每个栈的 push/pop 只操作自己的 path
  • 跨栈导航先切栈,再 push 目标路由
  • 记录来源栈,必要时支持“返回原栈”

实战问答

Q1:多栈会不会很重?
A:比单栈多一点管理成本,但换来可维护性,长期收益更高。

Q2:登录后怎么回到目标页?
A:保存一个 pendingRoute,登录成功后回放。

Q3:路由参数怎么传模型?
A:建议传轻量 ID,详情页自行拉取;大型模型直传会增加耦合与内存风险。

总结

多栈不是“更复杂”,而是把复杂度前置并结构化。
长期看,路由治理越早做,后续维护成本越低。

更多推荐