@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',
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',
},
});
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: [
],
});
app.use(VuePlugin, {
router,
log: logInstance,
});
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: '关于我们',
},
}
与 deppon-log 集成
当传入 log 实例时,会自动追踪路由变化:
import { VuePlugin as LogPlugin } from '@deppon/deppon-log';
import { VuePlugin as RouterPlugin } from '@deppon/deppon-router';
const logInstance = LogPlugin.init();
app.use(RouterPlugin, {
routes: [
],
log: logInstance,
});
路由变化时会自动触发以下埋点事件:
$route_before - 路由跳转前
$pageview - 页面浏览
智能获取路由参数(getQueryByRoute)
getQueryByRoute 是一个智能获取路由参数的方法,它会自动检测当前环境并获取相应的参数:
- 在 iframe 环境中:优先从父级获取 params(通过
getParentParams),同时合并当前路由的 query 参数
- 在非 iframe 环境中:从当前路由的 query 参数获取
基本用法
import { useRouter, useRoute } from '@deppon/deppon-router';
const router = useRouter();
const allParams = router.getQueryByRoute();
const sourceType = router.getQueryByRoute('sourceType');
const route = useRoute();
const allParams = route.value.getQueryByRoute();
const sourceType = route.value.getQueryByRoute('sourceType');
this.$router.getQueryByRoute('sourceType');
参数说明
key (string, 可选): 参数键名
- 如果提供
key,返回对应的参数值(不存在返回 null)
- 如果不提供
key,返回所有参数对象
参数获取逻辑
-
iframe 环境:
- 优先从父级获取 params(
top.Ext.getCmp('mainAreaPanel').params)
- 同时从当前路由 query 获取参数
- 合并两者:父级 params 作为基础,query 参数覆盖同名参数(query 优先级更高)
-
非 iframe 环境:
- 从当前路由 query 获取参数(
router.currentRoute.value.query)
使用示例
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,
};
},
};
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.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 回调中)动态添加路由后正常使用
更多示例
更多使用示例请参考项目文档或源码。