这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情
在一个完整的应用中,页面跳转是不可缺少的一部分,solid 也提供了一个路由处理库,它位于一个独立的仓库中 github.com/solidjs/sol… 。路由仓库中涉及到的 API 有很多,这一篇来看一下 solid-router 的主流程功能实现。
首先来看一下我们是如何使用路由功能的,首先我们会在应用的外层包装一个 Router 组件,在应用内部使用 useRoutes 创建路由,返回一个组件作为占位,在占位区域渲染对应的路由组件信息。当然还有其他的渲染方式,这里没涉及到的先略过,感兴趣可以自行阅读,这里我们来看涉及到的 Router 和 useRoutes 的实现。
Router 的实现很简单,
export const Router = (props: RouterProps) => {
const { source, url, base, data, out } = props;
const integration =
source || (isServer ? staticIntegration({ value: url || "" }) : pathIntegration());
const routerState = createRouterContext(integration, base, data, out);
return (
<RouterContextObj.Provider value={routerState}>{props.children}</RouterContextObj.Provider>
);
};
它本质上就是一个 Context 的 Provider,Context 可以共享数据信息,这里把 Context 放在外层,它的子组件就可以通过 Context 来共享路由内容,在 createRouterContext 中可以看到这些共享信息内容,包括参数、路径等多项路由的元数据信息,这些内容将会在后面使用到。
再来看 useRoutes:
export const useRoutes = (routes: RouteDefinition | RouteDefinition[], base?: string) => {
return () => <Routes base={base}>{routes as any}</Routes>;
};
返回的是一个 Routes 组件,这个组件里面就是处理路由渲染的逻辑,solid-router/components.tsx at main · solidjs/solid-router (github.com) 。
这里面做的就是匹配当前的路由信息,根据传入的路由配置查找相应的组件,之后渲染对应的组件内容,路由匹配的逻辑本身并不复杂,这部分逻辑可以根据需要选择阅读,这个组件最终返回的是这样的结构:
<Show when={routeStates() && root}>
{route => <RouteContextObj.Provider value={route}>{route.outlet()}</RouteContextObj.Provider>}
</Show>
这里的组件依旧会被 RouteContextObj 包裹,这里为其传入了 router 作为值,实际展示的内容是调用了 outlet,这里的 outlet 是在 createRouteContext 时传入的,match().route.element,对应了实际内容的渲染,这样就实现了根据不同的路径渲染组件内容。
有关 router 的全部内容当然不止这么多,还有一些辅助的方法和工具,这些大部分也都是基于 context 来实现的,如果在开发中有所涉及可以来查阅。