From a3dce0e0f26d7dc381aed7437ef8ff0144d54757 Mon Sep 17 00:00:00 2001
From: pany <939630029@qq.com>
Date: Mon, 28 Aug 2023 14:07:34 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20useRouteListener?=
=?UTF-8?q?=EF=BC=8C=E7=B3=BB=E7=BB=9F=E7=BB=9F=E4=B8=80=E9=87=87=E7=94=A8?=
=?UTF-8?q?=E8=AF=A5=20hook=20=E7=9B=91=E5=90=AC=E8=B7=AF=E7=94=B1?=
=?UTF-8?q?=E5=8F=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/hooks/useRouteListener.ts | 48 +++++++++++++++++++
src/layouts/components/Breadcrumb/index.vue | 15 +++---
.../components/TagsView/ScrollPane.vue | 20 ++++----
src/layouts/components/TagsView/index.vue | 22 ++++-----
src/layouts/hooks/useResize.ts | 19 ++++----
src/router/permission.ts | 8 +++-
src/utils/route-listener.ts | 33 -------------
7 files changed, 85 insertions(+), 80 deletions(-)
create mode 100644 src/hooks/useRouteListener.ts
delete mode 100644 src/utils/route-listener.ts
diff --git a/src/hooks/useRouteListener.ts b/src/hooks/useRouteListener.ts
new file mode 100644
index 0000000..c7114d6
--- /dev/null
+++ b/src/hooks/useRouteListener.ts
@@ -0,0 +1,48 @@
+import { onBeforeUnmount } from "vue"
+import mitt, { type Handler } from "mitt"
+import { type RouteLocationNormalized } from "vue-router"
+
+/** 回调函数的类型 */
+type Callback = (route: RouteLocationNormalized) => void
+
+const emitter = mitt()
+const key = Symbol("ROUTE_CHANGE")
+let latestRoute: RouteLocationNormalized
+
+/** 设置最新的路由信息,触发路由变化事件 */
+const setRouteChange = (to: RouteLocationNormalized) => {
+ // 触发事件
+ emitter.emit(key, to)
+ // 缓存最新的路由信息
+ latestRoute = to
+}
+
+/** 单独监听路由会浪费渲染性能,使用发布订阅模式去进行分发管理 */
+export function useRouteListener() {
+ /** 回调函数集合 */
+ const callbackList: Callback[] = []
+
+ /** 监听路由变化(可以选择立即执行) */
+ const listenerRouteChange = (callback: Callback, immediate = false) => {
+ // 缓存回调函数
+ callbackList.push(callback)
+ // 监听事件
+ emitter.on(key, callback as Handler)
+ // 可以选择立即执行一次回调函数
+ immediate && latestRoute && callback(latestRoute)
+ }
+
+ /** 移除路由变化事件监听器 */
+ const removeRouteListener = (callback: Callback) => {
+ emitter.off(key, callback as Handler)
+ }
+
+ /** 组件销毁前移除监听器 */
+ onBeforeUnmount(() => {
+ for (let i = 0; i < callbackList.length; i++) {
+ removeRouteListener(callbackList[i])
+ }
+ })
+
+ return { setRouteChange, listenerRouteChange, removeRouteListener }
+}
diff --git a/src/layouts/components/Breadcrumb/index.vue b/src/layouts/components/Breadcrumb/index.vue
index 90acb5d..b69998a 100644
--- a/src/layouts/components/Breadcrumb/index.vue
+++ b/src/layouts/components/Breadcrumb/index.vue
@@ -1,10 +1,12 @@
diff --git a/src/layouts/components/TagsView/index.vue b/src/layouts/components/TagsView/index.vue
index 65b0dce..13eab21 100644
--- a/src/layouts/components/TagsView/index.vue
+++ b/src/layouts/components/TagsView/index.vue
@@ -1,9 +1,9 @@
diff --git a/src/layouts/hooks/useResize.ts b/src/layouts/hooks/useResize.ts
index 88dd8de..284e372 100644
--- a/src/layouts/hooks/useResize.ts
+++ b/src/layouts/hooks/useResize.ts
@@ -1,6 +1,6 @@
-import { watch, onBeforeMount, onMounted, onBeforeUnmount } from "vue"
-import { useRoute } from "vue-router"
+import { onBeforeMount, onMounted, onBeforeUnmount } from "vue"
import { useAppStore } from "@/store/modules/app"
+import { useRouteListener } from "@/hooks/useRouteListener"
import { DeviceEnum } from "@/constants/app-key"
/** 参考 Bootstrap 的响应式设计将最大移动端宽度设置为 992 */
@@ -8,8 +8,8 @@ const MAX_MOBILE_WIDTH = 992
/** 根据浏览器宽度变化,变换 Layout 布局 */
export default () => {
- const route = useRoute()
const appStore = useAppStore()
+ const { listenerRouteChange } = useRouteListener()
/** 用于判断当前设备是否为移动端 */
const _isMobile = () => {
@@ -25,15 +25,12 @@ export default () => {
isMobile && appStore.closeSidebar(true)
}
}
- /** 监听路由名称变化,根据设备类型调整布局 */
- watch(
- () => route.name,
- () => {
- if (appStore.device === DeviceEnum.Mobile && appStore.sidebar.opened) {
- appStore.closeSidebar(false)
- }
+ /** 监听路由变化,根据设备类型调整布局 */
+ listenerRouteChange(() => {
+ if (appStore.device === DeviceEnum.Mobile && appStore.sidebar.opened) {
+ appStore.closeSidebar(false)
}
- )
+ })
/** 在组件挂载前添加窗口大小变化事件监听器 */
onBeforeMount(() => {
diff --git a/src/router/permission.ts b/src/router/permission.ts
index 25d8492..c22861f 100644
--- a/src/router/permission.ts
+++ b/src/router/permission.ts
@@ -2,19 +2,19 @@ import router from "@/router"
import { useUserStoreHook } from "@/store/modules/user"
import { usePermissionStoreHook } from "@/store/modules/permission"
import { ElMessage } from "element-plus"
+import { useRouteListener } from "@/hooks/useRouteListener"
import { getToken } from "@/utils/cache/cookies"
import { fixBlankPage } from "@/utils/fix-blank-page"
-import { setRouteEmitter } from "@/utils/route-listener"
import routeSettings from "@/config/route"
import isWhiteList from "@/config/white-list"
import NProgress from "nprogress"
import "nprogress/nprogress.css"
NProgress.configure({ showSpinner: false })
+const { setRouteChange } = useRouteListener()
router.beforeEach(async (to, _from, next) => {
fixBlankPage()
- setRouteEmitter(to)
NProgress.start()
const userStore = useUserStoreHook()
const permissionStore = usePermissionStoreHook()
@@ -70,6 +70,10 @@ router.beforeEach(async (to, _from, next) => {
}
})
+router.afterEach((to) => {
+ setRouteChange(to)
+})
+
router.afterEach(() => {
NProgress.done()
})
diff --git a/src/utils/route-listener.ts b/src/utils/route-listener.ts
deleted file mode 100644
index d753b61..0000000
--- a/src/utils/route-listener.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/** 单独监听路由会浪费渲染性能,使用发布订阅模式去进行分发管理 */
-
-import mitt, { type Handler } from "mitt"
-import { type RouteLocationNormalized } from "vue-router"
-
-/** 回调函数的类型 */
-type Callback = (route: RouteLocationNormalized) => void
-
-const emitter = mitt()
-const key = Symbol("ROUTE_CHANGE")
-let latestRoute: RouteLocationNormalized
-
-/** 设置最新的路由信息 */
-export const setRouteEmitter = (to: RouteLocationNormalized) => {
- emitter.emit(key, to)
- latestRoute = to
-}
-
-/** 设置路由变化时的回调函数(可以选择立即执行一次回调函数) */
-export const listenerRouteChange = (callback: Callback, immediate = false) => {
- emitter.on(key, callback as Handler)
- immediate && latestRoute && callback(latestRoute)
-}
-
-/** 移除路由变化事件监听器 */
-export const removeRouteListener = (callback: Callback) => {
- emitter.off(key, callback as Handler)
-}
-
-/** 移除所有路由变化事件监听器 */
-export const removeAllRouteListener = () => {
- emitter.off(key)
-}