Skip to content

跳转详情页路由工具 ​

简介 ​

use-goto-detail-page 是一个用于处理详情页跳转的组合式 API 工具,它与「基于路由名称的键值对存储工具」高度耦合,提供了一种便捷的方式来处理前驱页面和后继页面之间的关系,特别适用于列表页到详情页的跳转场景。

核心功能 ​

  1. 前后页面关系管理:自动处理前驱页面(如列表页)和后继页面(如详情页)之间的关系
  2. 自动路由信息存储:在跳转前自动存储前驱页面的路径信息
  3. 路由守卫集成:提供路由守卫处理函数,自动设置后继页面的 meta.activePath
  4. 类型安全:完全支持 Vue Router 的类型系统,确保类型安全

主要 API ​

useGotoDetailPage ​

组合式 API 函数,返回跳转详情页相关的工具函数。

typescript
function useGotoDetailPage(): {
	gotoDetailPage: (to: RouteLocationRaw) => Promise<void | NavigationFailure | undefined>;
	handleDetailPageBeforeEnter: (
		to: RouteLocationNormalized,
		from: RouteLocationNormalized,
		next: NavigationGuardNext,
	) => void;
};

gotoDetailPage ​

跳转到详情页的函数,支持与 router.push 相同的参数格式。

typescript
function gotoDetailPage(to: RouteLocationRaw): Promise<void | NavigationFailure | undefined>;

参数:

  • to: 路由位置,与 router.push 参数相同,可以是字符串路径或包含 name/path 的对象

返回值:

  • 返回 Promise,与 router.push 返回值相同

示例:

typescript
// 在组件中使用组合式 API
import { useGotoDetailPage } from "@/hooks/use-goto-detail-page";

const { gotoDetailPage } = useGotoDetailPage();

// 使用路由名称跳转
gotoDetailPage({ name: "user-detail", params: { id: 123 } });

// 使用路径跳转
gotoDetailPage("/user/detail/123");
typescript
// 直接使用独立函数
import { gotoDetailPage } from "@/hooks/use-goto-detail-page";

// 使用路由名称跳转
gotoDetailPage({ name: "user-detail", params: { id: 123 } });

handleDetailPageBeforeEnter ​

详情页路由守卫处理函数,用于在详情页的 beforeEnter 守卫中设置 meta.activePath。

typescript
function handleDetailPageBeforeEnter(
	to: RouteLocationNormalized,
	from: RouteLocationNormalized,
	next: NavigationGuardNext,
): void;

参数:

  • to: 目标路由对象
  • from: 来源路由对象
  • next: 路由守卫 next 函数

示例:

typescript
// 在路由配置中使用
import { handleDetailPageBeforeEnter } from "@/hooks/use-goto-detail-page";

const routes = [
	{
		path: "/user/detail/:id",
		name: "user-detail",
		component: () => import("@/pages/user/detail.vue"),
		beforeEnter: (to, from, next) => {
			handleDetailPageBeforeEnter(to, from, next);
			next();
		},
	},
];

详情页路由配置 ​

在详情页的路由配置中,有三种方式使用路由守卫:

1. 使用独立函数 ​

typescript
import { handleDetailPageBeforeEnter } from "@/hooks/use-goto-detail-page";

const routes = [
	{
		path: "/user/detail/:id",
		name: "user-detail",
		component: () => import("@/pages/user/detail.vue"),
		beforeEnter: (to, from, next) => {
			handleDetailPageBeforeEnter(to, from, next);
			next();
		},
	},
];

2. 自定义路由守卫 ​

typescript
import { handleDetailPageBeforeEnter } from "@/hooks/use-goto-detail-page";

// 自定义路由守卫
function customBeforeEnter(to, from, next) {
	// 处理详情页路由守卫
	handleDetailPageBeforeEnter(to, from, next);

	// 其他自定义逻辑
	console.log("进入详情页");

	next();
}

const routes = [
	{
		path: "/user/detail/:id",
		name: "user-detail",
		component: () => import("@/pages/user/detail.vue"),
		beforeEnter: customBeforeEnter,
	},
];

3. 在组件中使用组合式 API ​

typescript
// 在详情页组件中
import { useGotoDetailPage } from "@/hooks/use-goto-detail-page";
import { onBeforeRouteEnter } from "vue-router";

export default {
	setup() {
		const { handleDetailPageBeforeEnter } = useGotoDetailPage();

		onBeforeRouteEnter((to, from, next) => {
			next((instance) => {
				// 在组件实例创建后调用
				handleDetailPageBeforeEnter(to, from, () => {});
			});
		});

		// ...
	},
};

完整业务流程示例 ​

列表页面(前驱页) ​

typescript
<template>
  <div>
    <h1>用户列表</h1>
    <table>
      <tr v-for="user in users" :key="user.id">
        <td>{{ user.name }}</td>
        <td>
          <button @click="viewDetail(user.id)">查看详情</button>
        </td>
      </tr>
    </table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useGotoDetailPage } from '@/hooks/use-goto-detail-page';

const { gotoDetailPage } = useGotoDetailPage();

const users = ref([
  { id: 1, name: '张三' },
  { id: 2, name: '李四' },
  { id: 3, name: '王五' }
]);

function viewDetail(id: number) {
  // 跳转到详情页,自动保存当前页面路径
  gotoDetailPage({
    name: 'user-detail',
    params: { id }
  });
}
</script>

详情页面(后继页) ​

typescript
<template>
  <div>
    <h1>用户详情</h1>
    <div v-if="user">
      <p>ID: {{ user.id }}</p>
      <p>姓名: {{ user.name }}</p>
      <p>邮箱: {{ user.email }}</p>
    </div>
    <button @click="goBack">返回列表</button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';

const route = useRoute();
const router = useRouter();
const user = ref(null);

onMounted(async () => {
  // 获取用户ID
  const userId = route.params.id;

  // 加载用户数据
  // 实际应用中这里会调用API
  user.value = {
    id: userId,
    name: userId === '1' ? '张三' : userId === '2' ? '李四' : '王五',
    email: `user${userId}@example.com`
  };
});

function goBack() {
  // 返回前驱页面
  // 这里会使用 meta.activePath,由路由守卫自动设置
  if (route.meta.activePath) {
    router.push(route.meta.activePath as string);
  } else {
    // 如果没有前驱页面信息,返回默认列表页
    router.push('/user/list');
  }
}
</script>

路由配置 ​

typescript
import { handleDetailPageBeforeEnter } from "@/hooks/use-goto-detail-page";

const routes = [
	{
		path: "/user/list",
		name: "user-list",
		component: () => import("@/pages/user/list.vue"),
	},
	{
		path: "/user/detail/:id",
		name: "user-detail",
		component: () => import("@/pages/user/detail.vue"),
		// 使用路由守卫处理详情页
		beforeEnter: (to, from, next) => {
			handleDetailPageBeforeEnter(to, from, next);
			next();
		},
	},
];

核心流程 ​

前驱页跳转流程 ​

  1. 用户在列表页点击「查看详情」按钮
  2. 调用 gotoDetailPage 函数,传入目标路由信息
  3. 函数内部获取目标路由和当前路由信息
  4. 将当前路由路径(前驱页面路径)保存到路由信息存储中
  5. 跳转到详情页

后继页加载流程 ​

  1. 路由跳转到详情页
  2. 触发详情页的 beforeEnter 路由守卫
  3. 调用 handleDetailPageBeforeEnter 函数
  4. 函数内部从路由信息存储中获取保存的前驱页面路径
  5. 设置当前路由的 meta.activePath 为前驱页面路径
  6. 详情页组件可以使用 route.meta.activePath 实现返回前驱页面的功能

与路由信息存储工具的协作关系 ​

特性优势 ​

  1. 类型安全:完全支持 Vue Router 的类型系统,确保类型安全
  2. 自动化处理:自动处理前驱页面和后继页面之间的关系,减少手动代码
  3. 灵活使用:提供组合式 API 和独立函数两种使用方式,适应不同场景
  4. 错误处理:内置错误处理机制,防止因参数错误导致的异常

注意事项 ​

  1. 路由名称要求:目标路由必须有名称(name),否则无法正确存储和获取路由信息
  2. 路由守卫配置:详情页必须配置路由守卫并调用 handleDetailPageBeforeEnter 函数
  3. 存储清理:当不再需要某些路由信息时,可以使用路由信息存储工具的 removeRouteInfo 或 clearAllRouteInfo 方法清理

最佳实践 ​

  1. 在列表页使用 gotoDetailPage 替代 router.push 进行跳转
  2. 在详情页的路由配置中使用 handleDetailPageBeforeEnter 函数
  3. 在详情页的「返回」按钮中使用 route.meta.activePath 实现返回前驱页面
  4. 使用 TypeScript 类型系统确保类型安全

更新日志 ​

v1.0.0 ​

  • 初始版本
  • 实现基本的详情页跳转功能
  • 支持路由守卫集成
  • 提供组合式 API 和独立函数两种使用方式

贡献者

The avatar of contributor named as ruan-cat ruan-cat

页面历史

最近更新