类继承关系
export class RouterView extends TypeDiv implements IRouterView
基类:TypeDiv 提供基础DOM操作能力
接口:IRouterView 定义核心属性和方法
核心属性
private routerViewNumber: number; // 视图编号
readonly className: 'RouterView'; // 组件类型标识
props: RouterViewProps; // 路由视图属性
构造函数
constructor(params = {} as RouterViewProps) {
super();
this.className = 'RouterView';
this.routerViewNumber = routerViewDepth++;
// 设置DOM属性
this.attr.addObj({ name: 'router-view-' + this.routerViewNumber });
this.assignProps({ name: 'default' }); // 默认插槽名称
this.props = this.useParams(params); // 合并参数
}
依赖注入体系
// 注入路由上下文
const injectedRoute = inject(routerViewLocationKey)!;
const injectedDepth = inject(viewDepthKey, 0);
注入符号:
routerViewLocationKey:当前路由位置
viewDepthKey:嵌套深度
matchedRouteKey:匹配的路由记录
响应式状态管理
const routeToDisplay = computed(() => props.route || injectedRoute.get());
const depth = computed(() => {
let initialDepth = unref(injectedDepth)!;
const { matched } = routeToDisplay.get();
while (matched[initialDepth] && !matched[initialDepth].components) {
initialDepth++;
}
return initialDepth;
});
使用signals库实现响应式状态
动态计算嵌套深度和当前显示路由
组件生命周期
onMounted(() => {
// 监听路由变化
watch([routeToDisplay, matchedRouteRef], (to, from) => {
// 处理组件实例更新
// ...
}, { immediate: true });
});
使用signals的watch实现响应式监听
处理组件挂载/更新/卸载逻辑
组件加载机制
if (isRouteComponent(ViewComponent)) {
// 同步组件
component = new (ViewComponent as any)(props) as TypeElement;
} else {
// 异步组件
(ViewComponent as any)().then((module: Module) => {
const Component = getClassFromModule(module);
component = new Component(props);
});
}
支持同步/异步组件加载
使用getClassFromModule处理模块导入
导航守卫处理
// 复用导航守卫
if (fromRoute && fromRoute !== toRoute && instance && instance === oldInstance) {
if (!toRoute.leaveGuards.size) {
toRoute.leaveGuards = fromRoute.leaveGuards;
}
}
实现组件复用时的守卫继承
支持beforeRouteEnter等钩子回调
DOM更新策略
this.clearChildren();
this.addChild(component);
component.mount(this.dom);
使用框架提供的DOM操作方法
支持组件动态替换和更新
路由组件缓存
// 缓存组件实例
toRoute.instances[name!] = instance;
通过路由记录对象缓存组件实例
支持组件复用和状态保留
嵌套路由处理
provide(viewDepthKey, computed(() => depth.get() + 1));
使用依赖注入传递嵌套深度
支持多级路由视图渲染
与Vue Router对比
特性 | TypeDom RouterView | Vue RouterView |
---|---|---|
响应式系统 | signals库 | Vue Reactivity |
组件加载 | new Component() | h()函数 |
模块加载 | Module类型 | () => Promise |
DOM操作 | TypeElement API | Virtual DOM |
导航守卫 | 对象属性存储 | 路由实例 |
组件缓存 | matchedRoute.instances | keep-alive |
模块导入 | getClassFromModule() | require() |
插槽处理 | slotChildren() | h函数参数 |
实现特点
1.轻量级实现:基于signals库实现响应式,无需引入完整框架
2.渐进式设计:支持同步/异步组件加载,兼容不同使用场景
3.组件复用优化:通过实例缓存提升性能
4.导航守卫集成:完整实现路由守卫传递机制
5.类型安全:使用TypeScript泛型确保类型正确性
与其他模块关系
使用示例
// 基本使用
const view = new RouterView();
view.mount(document.getElementById('app'));
// 嵌套路由
const nestedView = new RouterView({ name: 'sub' });
parentView.addChild(nestedView);
设计启示
该实现借鉴了Vue Router的核心设计理念,但做了以下适配:
1.替换Vue响应式系统为signals库
2.使用TypeElement进行DOM操作
3.简化插槽处理逻辑
4.保持导航守卫的兼容性
5.支持TypeDom框架的组件模型
这种实现方式在保持路由功能完整性的同时,充分利用了TypeDom框架的基础能力,实现了轻量级的路由视图组件。