@deppon/deppon-router
v2.2.1
Published
Vue Router 4 wrapper package
Maintainers
Readme
@deppon/deppon-router
Vue Router 4 封装包
安装
npm install @deppon/deppon-router依赖说明:
vue-router已声明为peerDependencies,如果宿主项目已安装vue-router@^4.0.0,将优先使用宿主项目的版本,避免版本冲突- 如果宿主项目未安装
vue-router,会自动安装(因为也在dependencies中) - 建议宿主项目显式安装
vue-router@^4.0.0以确保版本一致性 - viewTab 相关功能已内置在
@deppon/deppon-router中,不再需要@deppon/deppon-utils依赖
功能特性
- ✅ 基于 Vue Router 4 封装
- ✅ 支持 Vue 3 插件安装方式
- ✅ 提供 Composition API (useRouter, useRoute)
- ✅ 支持路由守卫配置
- ✅ 自动路由追踪(与 deppon-log 集成)
- ✅ 提供路由工具函数
- ✅ 自动设置页面标题
- ✅ 安全的路由跳转(错误处理)
- ✅ 智能路由跳转(在 iframe 环境中自动使用 viewTab,否则使用 router.push)
基础使用
JavaScript/TypeScript 项目
import { createDepponRouter } from '@deppon/deppon-router';
// 创建路由实例
const router = createDepponRouter({
routes: [
{
path: '/',
name: 'Home',
component: () => import('./views/Home.vue'),
meta: {
title: '首页',
},
},
{
path: '/about',
name: 'About',
component: () => import('./views/About.vue'),
meta: {
title: '关于',
},
},
],
routerOptions: {
history: 'web', // 'web' | 'hash' | 'memory',默认为 'web'
base: '/',
},
});
export default router;Vue 3 使用
1. 安装插件
在 Vue 应用中安装插件:
import { createApp } from 'vue';
import { VuePlugin } from '@deppon/deppon-router';
import App from './App.vue';
const app = createApp(App);
// 安装插件
app.use(VuePlugin, {
routes: [
{
path: '/',
name: 'Home',
component: () => import('./views/Home.vue'),
meta: {
title: '首页',
},
},
],
routerOptions: {
history: 'web', // 'web' | 'hash' | 'memory'
},
});
app.mount('#app');2. 配置路由守卫
import { createApp } from 'vue';
import { VuePlugin } from '@deppon/deppon-router';
import App from './App.vue';
const app = createApp(App);
app.use(VuePlugin, {
routes: [
// ... 路由配置
],
guards: {
// 全局前置守卫
beforeEach(to, from, next) {
// 权限检查
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login');
} else {
next();
}
},
// 全局后置守卫
afterEach(to, from) {
// 路由变化后的处理
console.log('路由变化:', to.path);
},
// 全局解析守卫
beforeResolve(to, from, next) {
// 解析前的处理
next();
},
},
});
app.mount('#app');3. 与 deppon-log 集成
import { createApp } from 'vue';
import { VuePlugin } from '@deppon/deppon-router';
import { VuePlugin as LogPlugin } from '@deppon/deppon-log';
import App from './App.vue';
const app = createApp(App);
// 先创建路由实例
const router = createDepponRouter({
routes: [
// ... 路由配置
],
});
// 安装路由插件(传入 log 实例以启用自动路由追踪)
app.use(VuePlugin, {
router,
log: logInstance, // deppon-log 实例
});
// 或者使用插件方式
app.use(VuePlugin, {
routes: [
// ... 路由配置
],
log: logInstance,
});
app.mount('#app');4. 在 Composition API 中使用
<script setup>
import { useRouter, useRoute } from '@deppon/deppon-router';
import { ref } from 'vue';
const router = useRouter();
const route = useRoute();
// 获取当前路由信息
console.log(route.path);
console.log(route.params);
console.log(route.query);
// 路由跳转
const goToHome = () => {
router.push('/home');
};
// 使用工具方法
const goToAbout = () => {
router.pushByName('About', {}, {});
};
const goBack = () => {
router.goBack();
};
// 使用智能获取路由参数(自动适配 iframe 环境)
const route = useRoute();
const sourceType = route.value.getQueryByRoute('sourceType');
const allParams = route.value.getQueryByRoute();
// 使用智能路由跳转(在 iframe 环境中自动使用 viewTab)
const goToDetail = () => {
router.smartPush({
path: '/preferInfo',
query: { sourceType: 'insert' },
params: { custNumber: '701265308' },
_viewTab: {
title: 'CMC-产品折扣新增',
uumsFunction: {
functionCode: 'CMC_FUNCTION_00002',
sourceSystem: 'CMC',
},
closeCurrentTab: true,
},
});
};
</script>
<template>
<div>
<button @click="goToHome">去首页</button>
<button @click="goToAbout">去关于页</button>
<button @click="goBack">返回</button>
</div>
</template>5. 在 Options API 中使用
<script>
export default {
methods: {
goToHome() {
// 使用 this.$router 访问
this.$router.push('/home');
},
goToAbout() {
// 使用工具方法
this.$router.pushByName('About');
},
goBack() {
this.$router.goBack();
},
getParams() {
// 使用智能获取路由参数(自动适配 iframe 环境)
const allParams = this.$router.getQueryByRoute();
const sourceType = this.$router.getQueryByRoute('sourceType');
console.log('所有参数:', allParams);
console.log('sourceType:', sourceType);
},
goToDetail() {
// 使用智能路由跳转(在 iframe 环境中自动使用 viewTab)
this.$router.smartPush({
path: '/preferInfo',
query: { sourceType: 'insert' },
_viewTab: {
title: 'CMC-产品折扣新增',
closeCurrentTab: true,
},
});
},
},
mounted() {
// 访问当前路由
console.log(this.$route.path);
},
};
</script>API
createDepponRouter(options)
创建增强的 Vue Router 实例。
参数
options.routes- 路由配置数组(必填)options.routerOptions- Vue Router 原始配置选项(可选)history- 历史模式('web' | 'hash' | 'memory'),默认为 'web'base- 应用的基础路径scrollBehavior- 滚动行为函数- 其他 Vue Router 4 支持的选项
options.guards- 路由守卫配置(可选)beforeEach- 全局前置守卫afterEach- 全局后置守卫beforeResolve- 全局解析守卫
options.log- 日志实例(可选,用于路由追踪)options.onRouteChange- 路由变化回调(可选)
返回值
增强的 Vue Router 实例,包含以下额外方法:
safePush(location, onComplete, onAbort)- 安全的路由跳转safeReplace(location, onComplete, onAbort)- 安全的路由替换pushByName(name, params, query)- 根据路由名称跳转pushByPath(path, query)- 根据路由路径跳转goBack(delta)- 返回上一页hasRoute(name)- 检查路由是否存在(包括动态添加的路由)getRouteConfig(name)- 获取路由配置(包括动态添加的路由)smartPush(location, onComplete, onAbort)- 智能路由跳转(在 iframe 环境中自动使用 viewTab,否则使用 router.push)getQueryByRoute(key)- 智能获取路由参数(在 iframe 环境中优先从父级获取,否则从当前路由 query 获取)
Composition API
useRouter()
获取 router 实例。
import { useRouter } from '@deppon/deppon-router';
const router = useRouter();
router.push('/home');useRoute()
获取当前路由对象。
import { useRoute } from '@deppon/deppon-router';
const route = useRoute();
console.log(route.value.path);路由配置示例
const routes = [
{
path: '/',
name: 'Home',
component: () => import('./views/Home.vue'),
meta: {
title: '首页',
requiresAuth: false,
},
},
{
path: '/user',
name: 'User',
component: () => import('./views/User.vue'),
meta: {
title: '用户中心',
requiresAuth: true,
},
children: [
{
path: 'profile',
name: 'UserProfile',
component: () => import('./views/UserProfile.vue'),
meta: {
title: '个人资料',
},
},
],
},
];路由守卫示例
权限控制
app.use(VuePlugin, {
routes: [
// ... 路由配置
],
guards: {
beforeEach(to, from, next) {
// 检查是否需要登录
if (to.meta.requiresAuth && !isAuthenticated()) {
next({
path: '/login',
query: { redirect: to.fullPath },
});
} else {
next();
}
},
},
});页面标题管理
路由配置中的 meta.title 会自动设置为页面标题:
{
path: '/about',
name: 'About',
component: () => import('./views/About.vue'),
meta: {
title: '关于我们', // 会自动设置为 document.title
},
}与 deppon-log 集成
当传入 log 实例时,会自动追踪路由变化:
import { VuePlugin as LogPlugin } from '@deppon/deppon-log';
import { VuePlugin as RouterPlugin } from '@deppon/deppon-router';
// 初始化日志
const logInstance = LogPlugin.init(/* ... */);
// 安装路由插件,传入 log 实例
app.use(RouterPlugin, {
routes: [
// ... 路由配置
],
log: logInstance, // 自动追踪路由变化
});路由变化时会自动触发以下埋点事件:
$route_before- 路由跳转前$pageview- 页面浏览
智能获取路由参数(getQueryByRoute)
getQueryByRoute 是一个智能获取路由参数的方法,它会自动检测当前环境并获取相应的参数:
- 在 iframe 环境中:优先从父级获取 params(通过
getParentParams),同时合并当前路由的 query 参数 - 在非 iframe 环境中:从当前路由的 query 参数获取
基本用法
import { useRouter, useRoute } from '@deppon/deppon-router';
// 方式1:通过 router 实例使用
const router = useRouter();
const allParams = router.getQueryByRoute(); // 获取所有参数
const sourceType = router.getQueryByRoute('sourceType'); // 获取指定参数
// 方式2:通过 route 对象使用(推荐)
const route = useRoute();
const allParams = route.value.getQueryByRoute(); // 获取所有参数
const sourceType = route.value.getQueryByRoute('sourceType'); // 获取指定参数
// 方式3:在 Options API 中使用
this.$router.getQueryByRoute('sourceType');参数说明
key(string, 可选): 参数键名- 如果提供
key,返回对应的参数值(不存在返回null) - 如果不提供
key,返回所有参数对象
- 如果提供
参数获取逻辑
iframe 环境:
- 优先从父级获取 params(
top.Ext.getCmp('mainAreaPanel').params) - 同时从当前路由 query 获取参数
- 合并两者:父级 params 作为基础,query 参数覆盖同名参数(query 优先级更高)
- 优先从父级获取 params(
非 iframe 环境:
- 从当前路由 query 获取参数(
router.currentRoute.value.query)
- 从当前路由 query 获取参数(
使用示例
// 在 Composition API 中使用
import { useRoute } from '@deppon/deppon-router';
export default {
setup() {
const route = useRoute();
// 获取所有参数
const params = route.value.getQueryByRoute();
console.log('所有参数:', params);
// 获取指定参数
const sourceType = route.value.getQueryByRoute('sourceType');
const custNumber = route.value.getQueryByRoute('custNumber');
return {
sourceType,
custNumber,
};
},
};
// 在 Options API 中使用
export default {
mounted() {
// 获取所有参数
const params = this.$router.getQueryByRoute();
console.log('所有参数:', params);
// 获取指定参数
const sourceType = this.$router.getQueryByRoute('sourceType');
},
};替换原有代码示例
原代码(需要手动判断环境):
export function getQueryByRoute(key) {
let params;
if (top && top.viewTab) {
params =
(top.Ext && top.Ext.getCmp && top.Ext.getCmp('mainAreaPanel') && top.Ext.getCmp('mainAreaPanel').params) ||
{};
} else {
params = router.currentRoute.query;
}
return !key ? params : params ? params[key] : null;
}新代码(自动适配):
import { useRoute } from '@deppon/deppon-router';
const route = useRoute();
const sourceType = route.value.getQueryByRoute('sourceType');注意事项
getQueryByRoute在 iframe 环境中会自动从父级获取参数,无需额外依赖- 在 iframe 环境中,父级 params 和路由 query 参数会被合并,query 参数优先级更高
- 如果参数不存在,返回
null(当提供 key 时)或空对象{}(当不提供 key 时)
智能路由跳转(smartPush)
smartPush 是一个智能路由跳转方法,它会自动检测当前环境:
- 如果在 iframe 环境中且父级支持
viewTab,则自动使用viewTab进行跳转 - 否则使用普通的
router.push进行跳转
基本用法
smartPush 的参数传递方式与 router.push 完全一致:
// 字符串路径
router.smartPush('/home');
// 对象格式(与 router.push 一致)
router.smartPush({ path: '/home', query: { id: 1 } });
router.smartPush({ name: 'Home', params: { id: 1 } });iframe 环境中的使用
在 iframe 环境中,可以通过 _viewTab 选项自定义 viewTab 行为:
router.smartPush({
path: '/preferInfo',
query: { sourceType: 'insert' },
params: { custNumber: '701265308', preferId: '1312' },
_viewTab: {
title: 'CMC-产品折扣新增', // 标签页标题
uumsFunction: {
functionCode: 'CMC_FUNCTION_00002',
sourceSystem: 'CMC',
},
closeCurrentTab: true, // 是否关闭当前标签页
},
});_viewTab 选项说明
title(string, 可选): 标签页标题,默认使用路由meta.title或 '新页面'uumsFunction(object, 可选): UUMS 功能配置functionCode(string): 功能代码sourceSystem(string): 来源系统
closeCurrentTab(boolean, 可选): 是否关闭当前标签页,默认为false
替换原有代码示例
原代码(需要手动判断环境):
if (top.viewTab) {
let params = { sourceType: 'insert' };
let url = location.origin + '/#/preferInfo?sourceType=insert';
let tabUrl = top.Ext.urlAppend(url, 'isUap=true');
top.closeTab(tabUrl, 'IFRAME');
top.viewTab('CMC-产品折扣新增', url, 'iframe', params, {
uumsFunction: {
functionCode: 'CMC_FUNCTION_00002',
sourceSystem: 'CMC',
},
});
} else {
this.$router.push({
path: '/preferInfo',
query: { sourceType: 'insert' },
});
}新代码(自动适配):
router.smartPush({
path: '/preferInfo',
query: { sourceType: 'insert' },
params: { sourceType: 'insert' },
_viewTab: {
title: 'CMC-产品折扣新增',
uumsFunction: {
functionCode: 'CMC_FUNCTION_00002',
sourceSystem: 'CMC',
},
closeCurrentTab: true,
},
});smartPush 注意事项
smartPush内置了 viewTab 功能,无需额外依赖- 如果不在 iframe 环境中,会自动降级为
router.push _viewTab选项仅在 iframe 环境中生效,非 iframe 环境会被忽略params参数会传递给viewTab的params参数,query会转换为 URL 的 query string
注意事项
- 本包基于 Vue Router 4,需要安装
vue-router@^4.0.0 - 路由守卫中的
beforeEach如果返回false,会阻止导航 - 路由守卫中的
beforeEach如果返回 Promise,会等待 Promise 完成后再导航 - 使用
safePush和safeReplace可以避免导航重复的错误 - 路由配置中的
meta.title会自动设置为页面标题 smartPush和getQueryByRoute已内置 viewTab 相关功能,无需额外依赖getQueryByRoute在 iframe 环境中会自动合并父级 params 和路由 query 参数,query 参数优先级更高hasRoute和getRouteConfig支持检测通过router.addRoute()动态添加的路由,可以在登录后(如onLoggedIn回调中)动态添加路由后正常使用
更多示例
更多使用示例请参考项目文档或源码。
