From 15cae333a36472f4ce45f8b213b554deb6b985f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=AE=B6=E8=AE=AD?= Date: Thu, 10 Sep 2026 09:55:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=94=B9=E6=9E=AA?= =?UTF-8?q?=E7=A0=81=E5=BD=95=E5=85=A5=E9=A1=B5=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=B7=B1=E9=93=BE=E6=8E=A5=E4=B8=8E=E6=A0=87=E7=AD=BE=E6=A0=8F?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E5=9B=9E=E9=A6=96=E9=A1=B5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/components/tags-nav/tags-nav.vue | 8 +- src/components/main/main.vue | 7 + src/router/index.js | 37 +- src/view/delta/delta-gun-code-entry.vue | 315 ++++++++++++++++++ 4 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 src/view/delta/delta-gun-code-entry.vue diff --git a/src/components/main/components/tags-nav/tags-nav.vue b/src/components/main/components/tags-nav/tags-nav.vue index e87f7b4..5f97f60 100644 --- a/src/components/main/components/tags-nav/tags-nav.vue +++ b/src/components/main/components/tags-nav/tags-nav.vue @@ -197,8 +197,12 @@ export default { } }, mounted () { - // 默认关闭所有的标签 - this.handleTagsOption('all') + // 默认关闭所有的标签(仅在进入首页时重置)。 + // 注意:直接输入地址/刷新进入子页面时不能重置,因为 handleTagsOption('all') 会触发 + // 父组件的 handleCloseTag(res, 'all'),进而 turnToPage('home') 把页面弹回首页,导致深链接失效。 + if (this.$route.name === this.$config.homeName) { + this.handleTagsOption('all') + } setTimeout(() => { this.getTagElementByName(this.$route) }, 200) diff --git a/src/components/main/main.vue b/src/components/main/main.vue index adc2469..5ea902a 100644 --- a/src/components/main/main.vue +++ b/src/components/main/main.vue @@ -154,6 +154,13 @@ export default { this.addTag({ route: this.$store.state.app.homeRoute }) + // 直接输入地址/刷新进入时,localStorage 恢复的标签栏里没有当前页面, + // 这里把它补进标签栏,而不是直接跳回首页,否则深链接会被弹回首页 + if (this.$route.name && this.$route.name !== this.$config.homeName) { + this.addTag({ + route: this.$route + }) + } this.setBreadCrumb(this.$route) // 如果当前打开页面不在标签栏中,跳到homeName页 if (!this.tagNavList.find(item => item.name === this.$route.name)) { diff --git a/src/router/index.js b/src/router/index.js index 1c84c8f..fa833b4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -24,6 +24,7 @@ const router = new Router({ routes, mode: 'history' }) + const LOGIN_PAGE_NAME = 'login' const turnTo = (to, access, next) => { @@ -31,6 +32,36 @@ const turnTo = (to, access, next) => { else next({replace: true, name: 'error_401'}) // 无权限,重定向到401页面 } +// 应用首次加载时的地址(此时 vue-router 尚未改写 URL),作为深链接兜底 +const ENTRY_PATH = window.location.pathname + window.location.search + window.location.hash + +/** + * 修正「直接输入地址 / 刷新页面」时深链接失效的问题。 + * + * 动态菜单路由是在首次导航的守卫里才 addRoutes 的,而 vue-router 在进入守卫之前 + * 就已经用通配符路由(path: '*' → redirect: '/home')把未注册的地址重定向掉了, + * 所以守卫里拿到的 to 已经是 /home,原始地址只保留在 to.redirectedFrom 中 + * (vue-router 3.x 存的是 fullPath 字符串),表现为访问 /delta/gun-code 后停在首页「无反应」。 + * + * 这里在动态路由注册完成后,用新的 matcher 重新匹配原始地址:命中真实路由则再跳一次。 + * @returns {Boolean} 是否已重新发起跳转(true 时调用方不要再调用 next) + */ +const turnToRedirectedFrom = (to, next) => { + const redirectedFrom = to.redirectedFrom + // 兼容字符串(vue-router 3.x 实际类型)与对象两种形态,取不到时回退到入口地址 + const fromPath = typeof redirectedFrom === 'string' + ? redirectedFrom + : (redirectedFrom && redirectedFrom.path) || ENTRY_PATH + // 根路径本身就会重定向到首页;已经停在目标地址也无需再跳 + if (!fromPath || fromPath === '/' || fromPath === to.fullPath) return false + const matched = router.match(fromPath) + if (matched.matched.length > 0 && matched.name !== '_no_match') { + next({ path: fromPath, replace: true }) + return true + } + return false +} + router.beforeEach((to, from, next) => { iView.LoadingBar.start() const token = getToken() @@ -67,7 +98,8 @@ router.beforeEach((to, from, next) => { // 刷新界面菜单 store.commit('updateMenuList', list) - next() + // 动态路由已注册,若本次是深链接(被通配符重定向过)则回到原始地址 + if (!turnToRedirectedFrom(to, next)) next() }).catch(() => { // 获取权限失败,直接放行(保留基础路由),避免卡死 next() @@ -75,7 +107,8 @@ router.beforeEach((to, from, next) => { } else { let list = formatMenuList(JSON.parse(menuListStr)) store.commit('updateMenuList', list) - next() + // 动态路由已注册,若本次是深链接(被通配符重定向过)则回到原始地址 + if (!turnToRedirectedFrom(to, next)) next() } }).catch(() => { diff --git a/src/view/delta/delta-gun-code-entry.vue b/src/view/delta/delta-gun-code-entry.vue new file mode 100644 index 0000000..977bb4c --- /dev/null +++ b/src/view/delta/delta-gun-code-entry.vue @@ -0,0 +1,315 @@ + + + + +