From 23ab6b7ab55872abb25ab3aa7824f1107dd0aaac Mon Sep 17 00:00:00 2001 From: pany <939630029@qq.com> Date: Mon, 25 Nov 2024 14:21:18 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=BB=9F=E4=B8=80=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC=20(=E5=85=81=E8=AE=B8=E9=A1=B6=E5=B1=82?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E9=87=87=E7=94=A8=20/**=20=E5=86=85=E5=B1=82?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E9=87=87=E7=94=A8=E9=BB=98=E8=AE=A4=E7=9A=84?= =?UTF-8?q?=20//)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/styles/vxe-table.css | 28 ++++++++-------- src/composables/useDevice.ts | 1 + src/composables/useFetchSelect.ts | 3 +- src/composables/useFullscreenLoading.ts | 3 +- src/composables/useLayoutMode.ts | 1 + src/composables/usePagination.ts | 7 ++-- src/composables/useRouteListener.ts | 12 ++++--- src/composables/useTitle.ts | 1 + src/composables/useWatermark.ts | 30 ++++++++--------- src/layouts/components/Breadcrumb/index.vue | 2 +- .../components/TagsView/ScrollPane.vue | 8 ++--- src/layouts/composables/useResize.ts | 18 +++++++---- src/pages/login/composables/useFocus.ts | 8 +++-- src/pinia/stores/app.ts | 14 ++++---- src/pinia/stores/permission.ts | 12 +++---- src/pinia/stores/settings.ts | 8 ++--- src/pinia/stores/tags-view.ts | 4 +-- src/pinia/stores/user.ts | 16 +++++----- src/router/index.ts | 10 +++--- tsconfig.json | 8 +++-- types/vue-router.d.ts | 32 +++++++++---------- vite.config.ts | 6 ++-- 22 files changed, 125 insertions(+), 107 deletions(-) diff --git a/src/assets/styles/vxe-table.css b/src/assets/styles/vxe-table.css index 13bd1d4..8282936 100644 --- a/src/assets/styles/vxe-table.css +++ b/src/assets/styles/vxe-table.css @@ -5,7 +5,7 @@ */ :root { - /*color*/ + /* color */ --vxe-font-color: var(--el-text-color-regular); --vxe-primary-color: var(--el-color-primary); --vxe-success-color: var(--el-color-success); @@ -34,16 +34,16 @@ --vxe-warning-disabled-color: var(--el-color-warning-light-5); --vxe-danger-disabled-color: var(--el-color-danger-light-5); - /*input/radio/checkbox*/ + /* input/radio/checkbox */ --vxe-input-border-color: var(--el-border-color); --vxe-input-disabled-color: var(--el-text-color-disabled); --vxe-input-disabled-background-color: var(--el-fill-color-light); --vxe-input-placeholder-color: var(--el-text-color-placeholder); - /*popup*/ + /* popup */ --vxe-table-popup-border-color: var(--el-border-color); - /*table*/ + /* table */ --vxe-table-header-font-color: var(--el-text-color-regular); --vxe-table-footer-font-color: var(--el-text-color-regular); --vxe-table-border-color: var(--el-border-color-lighter); @@ -57,41 +57,41 @@ --vxe-table-checkbox-range-background-color: var(--el-fill-color-light); - /*menu*/ + /* menu */ --vxe-table-menu-background-color: var(--el-bg-color-overlay); - /*loading*/ + /* loading */ --vxe-loading-color: var(--el-color-primary); --vxe-loading-background-color: var(--el-mask-color); - /*validate*/ + /* validate */ --vxe-table-validate-error-color: var(--el-color-danger); - /*toolbar*/ + /* toolbar */ --vxe-toolbar-background-color: var(--el-bg-color); --vxe-toolbar-custom-active-background-color: var(--el-bg-color-overlay); --vxe-toolbar-panel-background-color: var(--el-bg-color-overlay); - /*pager*/ + /* pager */ --vxe-pager-background-color: var(--el-bg-color); - /*modal*/ + /* modal */ --vxe-modal-header-background-color: var(--el-bg-color); --vxe-modal-body-background-color: var(--el-bg-color); --vxe-modal-border-color: var(--el-border-color); - /*button*/ + /* button */ --vxe-button-default-background-color: var(--el-bg-color-overlay); - /*input*/ + /* input */ --vxe-input-background-color: var(--el-fill-color-blank); --vxe-input-panel-background-color: var(--el-fill-color-blank); - /*form*/ + /* form */ --vxe-form-background-color: var(--el-bg-color); --vxe-form-validate-error-color: var(--el-color-danger); - /*select*/ + /* select */ --vxe-select-option-hover-background-color: var(--el-bg-color-overlay); --vxe-select-panel-background-color: var(--el-bg-color); } diff --git a/src/composables/useDevice.ts b/src/composables/useDevice.ts index a27f587..62de52d 100644 --- a/src/composables/useDevice.ts +++ b/src/composables/useDevice.ts @@ -6,6 +6,7 @@ const appStore = useAppStore() const isMobile = computed(() => appStore.device === DeviceEnum.Mobile) const isDesktop = computed(() => appStore.device === DeviceEnum.Desktop) +/** 设备类型 Composable */ export function useDevice() { return { isMobile, isDesktop } } diff --git a/src/composables/useFetchSelect.ts b/src/composables/useFetchSelect.ts index 1517745..000954f 100644 --- a/src/composables/useFetchSelect.ts +++ b/src/composables/useFetchSelect.ts @@ -17,6 +17,7 @@ interface FetchSelectProps { api: () => Promise } +/** 下拉选择器 Composable */ export function useFetchSelect(props: FetchSelectProps) { const { api } = props @@ -24,7 +25,7 @@ export function useFetchSelect(props: FetchSelectProps) { const options = ref([]) const value = ref("") - /** 调用接口获取数据 */ + // 调用接口获取数据 const loadData = () => { loading.value = true options.value = [] diff --git a/src/composables/useFullscreenLoading.ts b/src/composables/useFullscreenLoading.ts index 1572aad..802c3c6 100644 --- a/src/composables/useFullscreenLoading.ts +++ b/src/composables/useFullscreenLoading.ts @@ -18,7 +18,8 @@ const DEFAULT_OPTIONS = { } /** - * 传入一个函数 fn,在它执行周期内,加上「全屏」Loading + * @name 全屏加载 Composable + * @description 传入一个函数 fn,在它执行周期内,加上「全屏」Loading * @param fn 要执行的函数 * @param options LoadingOptions * @returns 返回一个新的函数,该函数返回一个 Promise diff --git a/src/composables/useLayoutMode.ts b/src/composables/useLayoutMode.ts index 2c66369..06b2ddf 100644 --- a/src/composables/useLayoutMode.ts +++ b/src/composables/useLayoutMode.ts @@ -11,6 +11,7 @@ function setLayoutMode(mode: LayoutModeEnum) { settingsStore.layoutMode = mode } +/** 布局模式 Composable */ export function useLayoutMode() { return { isLeft, isTop, isLeftTop, setLayoutMode } } diff --git a/src/composables/usePagination.ts b/src/composables/usePagination.ts index a3f8524..3b7659c 100644 --- a/src/composables/usePagination.ts +++ b/src/composables/usePagination.ts @@ -17,14 +17,15 @@ const DEFAULT_PAGINATION_DATA = { layout: "total, sizes, prev, pager, next, jumper" } +/** 分页 Composable */ export function usePagination(initPaginationData: PaginationData = {}) { - /** 合并分页参数 */ + // 合并分页参数 const paginationData = reactive({ ...DEFAULT_PAGINATION_DATA, ...initPaginationData }) - /** 改变当前页码 */ + // 改变当前页码 const handleCurrentChange = (value: number) => { paginationData.currentPage = value } - /** 改变页面大小 */ + // 改变每页显示条数 const handleSizeChange = (value: number) => { paginationData.pageSize = value } diff --git a/src/composables/useRouteListener.ts b/src/composables/useRouteListener.ts index 6f1ee1e..28fe60e 100644 --- a/src/composables/useRouteListener.ts +++ b/src/composables/useRouteListener.ts @@ -17,12 +17,16 @@ export function setRouteChange(to: RouteLocationNormalized) { latestRoute = to } -/** 单独监听路由会浪费渲染性能,使用发布订阅模式去进行分发管理 */ +/** + * 订阅路由变化 Composable + * 1. 单独用 watch 监听路由会浪费渲染性能 + * 2. 可优先选择使用该发布订阅模式去进行分发管理 + */ export function useRouteListener() { // 回调函数集合 const callbackList: Callback[] = [] - /** 监听路由变化(可以选择立即执行) */ + // 监听路由变化(可以选择立即执行) const listenerRouteChange = (callback: Callback, immediate = false) => { // 缓存回调函数 callbackList.push(callback) @@ -32,12 +36,12 @@ export function useRouteListener() { 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]) diff --git a/src/composables/useTitle.ts b/src/composables/useTitle.ts index 1b2ce83..2c8bf99 100644 --- a/src/composables/useTitle.ts +++ b/src/composables/useTitle.ts @@ -18,6 +18,7 @@ watch(dynamicTitle, (value, oldValue) => { } }) +/** 标题 Composable */ export function useTitle() { return { setTitle } } diff --git a/src/composables/useWatermark.ts b/src/composables/useWatermark.ts index a7b0462..18376a8 100644 --- a/src/composables/useWatermark.ts +++ b/src/composables/useWatermark.ts @@ -34,25 +34,25 @@ const DEFAULT_CONFIG = { const bodyEl = ref(document.body) /** - * 创建水印 + * 水印 Composable * 1. 可以选择传入挂载水印的容器元素,默认是 body * 2. 做了水印防御,能有效防御别人打开控制台删除或隐藏水印 */ export function useWatermark(parentEl: Ref = bodyEl) { - /** 备份文本 */ + // 备份文本 let backupText: string - /** 最终配置 */ + // 最终配置 let mergeConfig: DefaultConfig - /** 水印元素 */ + // 水印元素 let watermarkEl: HTMLElement | null = null - /** 观察器 */ + // 观察器 const observer: Observer = { watermarkElMutationObserver: undefined, parentElMutationObserver: undefined, parentElResizeObserver: undefined } - /** 设置水印 */ + // 设置水印 const setWatermark = (text: string, config: Partial = {}) => { if (!parentEl.value) return console.warn("请在 DOM 挂载完成后再调用 setWatermark 方法设置水印") // 备份文本 @@ -65,7 +65,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { addElListener(parentEl.value) } - /** 创建水印元素 */ + // 创建水印元素 const createWatermarkEl = () => { const isBody = parentEl.value!.tagName.toLowerCase() === bodyEl.value.tagName.toLowerCase() const watermarkElPosition = isBody ? "fixed" : "absolute" @@ -84,7 +84,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { parentEl.value!.appendChild(watermarkEl) } - /** 更新水印元素 */ + // 更新水印元素 const updateWatermarkEl = ( options: Partial<{ width: number @@ -97,7 +97,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { options.height && (watermarkEl.style.height = `${options.height}px`) } - /** 创建 base64 图片 */ + // 创建 base64 图片 const createBase64 = () => { const { color, opacity, size, family, angle, width, height } = mergeConfig const canvasEl = document.createElement("canvas") @@ -114,7 +114,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { return canvasEl.toDataURL() } - /** 清除水印 */ + // 清除水印 const clearWatermark = () => { if (!parentEl.value || !watermarkEl) return // 移除对水印元素和容器元素的监听 @@ -130,14 +130,14 @@ export function useWatermark(parentEl: Ref = bodyEl) { } } - /** 刷新水印(防御时调用) */ + // 刷新水印(防御时调用) const updateWatermark = debounce(() => { clearWatermark() createWatermarkEl() addElListener(parentEl.value!) }, 100) - /** 监听水印元素和容器元素的变化(DOM 变化 & DOM 大小变化) */ + // 监听水印元素和容器元素的变化(DOM 变化 & DOM 大小变化) const addElListener = (targetNode: HTMLElement) => { // 判断是否开启防御 if (mergeConfig.defense) { @@ -157,7 +157,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { } } - /** 移除对水印元素和容器元素的监听,传参可指定要移除哪个监听,不传默认移除全部监听 */ + // 移除对水印元素和容器元素的监听,传参可指定要移除哪个监听,不传默认移除全部监听 const removeListener = (kind: "mutation" | "resize" | "all" = "all") => { // 移除 mutation 监听 if (kind === "mutation" || kind === "all") { @@ -173,7 +173,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { } } - /** 监听 DOM 变化 */ + // 监听 DOM 变化 const addMutationListener = (targetNode: HTMLElement) => { // 当观察到变动时执行的回调 const mutationCallback = debounce((mutationList: MutationRecord[]) => { @@ -212,7 +212,7 @@ export function useWatermark(parentEl: Ref = bodyEl) { }) } - /** 监听 DOM 大小变化 */ + // 监听 DOM 大小变化 const addResizeListener = (targetNode: HTMLElement) => { // 当 targetNode 元素大小变化时去更新整个水印的大小 const resizeCallback = debounce(() => { diff --git a/src/layouts/components/Breadcrumb/index.vue b/src/layouts/components/Breadcrumb/index.vue index 205453b..236fd38 100644 --- a/src/layouts/components/Breadcrumb/index.vue +++ b/src/layouts/components/Breadcrumb/index.vue @@ -33,7 +33,7 @@ function handleLink(item: RouteLocationMatched) { router.push(pathCompile(path)) } -/** 监听路由变化,更新面包屑导航信息 */ +// 监听路由变化,更新面包屑导航信息 listenerRouteChange((route) => { if (route.path.startsWith("/redirect/")) return getBreadcrumb() diff --git a/src/layouts/components/TagsView/ScrollPane.vue b/src/layouts/components/TagsView/ScrollPane.vue index ae88c5c..cb7314a 100644 --- a/src/layouts/components/TagsView/ScrollPane.vue +++ b/src/layouts/components/TagsView/ScrollPane.vue @@ -44,11 +44,11 @@ function wheelScroll({ deltaY }: WheelEvent) { /** 获取可能需要的宽度 */ function getWidth() { - /** 可滚动内容的长度 */ + // 可滚动内容的长度 const scrollbarContentRefWidth = scrollbarContentRef.value!.clientWidth - /** 滚动可视区宽度 */ + // 滚动可视区宽度 const scrollbarRefWidth = scrollbarRef.value!.wrapRef!.clientWidth - /** 最后剩余可滚动的宽度 */ + // 最后剩余可滚动的宽度 const lastDistance = scrollbarContentRefWidth - scrollbarRefWidth - currentScrollLeft return { scrollbarContentRefWidth, scrollbarRefWidth, lastDistance } @@ -96,7 +96,7 @@ function moveTo() { } } -/** 监听路由变化,移动到目标位置 */ +// 监听路由变化,移动到目标位置 listenerRouteChange(() => { nextTick(moveTo) }) diff --git a/src/layouts/composables/useResize.ts b/src/layouts/composables/useResize.ts index e1f7ab1..4a7336a 100644 --- a/src/layouts/composables/useResize.ts +++ b/src/layouts/composables/useResize.ts @@ -6,18 +6,21 @@ import { onBeforeMount, onBeforeUnmount, onMounted } from "vue" /** 参考 Bootstrap 的响应式设计将最大移动端宽度设置为 992 */ const MAX_MOBILE_WIDTH = 992 -/** 根据浏览器宽度变化,变换 Layout 布局 */ +/** + * @name 浏览器宽度变化 Composable + * @description 根据浏览器宽度变化,变换 Layout 布局 + */ export default () => { const appStore = useAppStore() const { listenerRouteChange } = useRouteListener() - /** 用于判断当前设备是否为移动端 */ + // 用于判断当前设备是否为移动端 const _isMobile = () => { const rect = document.body.getBoundingClientRect() return rect.width - 1 < MAX_MOBILE_WIDTH } - /** 用于处理窗口大小变化事件 */ + // 用于处理窗口大小变化事件 const _resizeHandler = () => { if (!document.hidden) { const isMobile = _isMobile() @@ -25,19 +28,20 @@ export default () => { isMobile && appStore.closeSidebar(true) } } - /** 监听路由变化,根据设备类型调整布局 */ + + // 监听路由变化,根据设备类型调整布局 listenerRouteChange(() => { if (appStore.device === DeviceEnum.Mobile && appStore.sidebar.opened) { appStore.closeSidebar(false) } }) - /** 在组件挂载前添加窗口大小变化事件监听器 */ + // 在组件挂载前添加窗口大小变化事件监听器 onBeforeMount(() => { window.addEventListener("resize", _resizeHandler) }) - /** 在组件挂载后根据窗口大小判断设备类型并调整布局 */ + // 在组件挂载后根据窗口大小判断设备类型并调整布局 onMounted(() => { if (_isMobile()) { appStore.toggleDevice(DeviceEnum.Mobile) @@ -45,7 +49,7 @@ export default () => { } }) - /** 在组件卸载前移除窗口大小变化事件监听器 */ + // 在组件卸载前移除窗口大小变化事件监听器 onBeforeUnmount(() => { window.removeEventListener("resize", _resizeHandler) }) diff --git a/src/pages/login/composables/useFocus.ts b/src/pages/login/composables/useFocus.ts index b6204e3..08ac3c0 100644 --- a/src/pages/login/composables/useFocus.ts +++ b/src/pages/login/composables/useFocus.ts @@ -1,14 +1,16 @@ import { ref } from "vue" +/** 焦点 Composable */ export function useFocus() { - /** 是否有焦点 */ + // 是否有焦点 const isFocus = ref(false) - /** 失去焦点 */ + // 失去焦点 const handleBlur = () => { isFocus.value = false } - /** 获取焦点 */ + + // 获取焦点 const handleFocus = () => { isFocus.value = true } diff --git a/src/pinia/stores/app.ts b/src/pinia/stores/app.ts index 1b8eb07..11efe5a 100644 --- a/src/pinia/stores/app.ts +++ b/src/pinia/stores/app.ts @@ -15,12 +15,12 @@ function handleSidebarStatus(opened: boolean) { } export const useAppStore = defineStore("app", () => { - /** 侧边栏状态 */ + // 侧边栏状态 const sidebar: Sidebar = reactive({ opened: getSidebarStatus() !== SIDEBAR_CLOSED, withoutAnimation: false }) - /** 设备类型 */ + // 设备类型 const device = ref(DeviceEnum.Desktop) // 监听侧边栏 opened 状态 @@ -29,17 +29,17 @@ export const useAppStore = defineStore("app", () => { opened => handleSidebarStatus(opened) ) - /** 切换侧边栏 */ + // 切换侧边栏 const toggleSidebar = (withoutAnimation: boolean) => { sidebar.opened = !sidebar.opened sidebar.withoutAnimation = withoutAnimation } - /** 关闭侧边栏 */ + // 关闭侧边栏 const closeSidebar = (withoutAnimation: boolean) => { sidebar.opened = false sidebar.withoutAnimation = withoutAnimation } - /** 切换设备类型 */ + // 切换设备类型 const toggleDevice = (value: DeviceEnum) => { device.value = value } @@ -48,8 +48,8 @@ export const useAppStore = defineStore("app", () => { }) /** - * 在 SPA 应用中可用于在 pinia 实例被激活前使用 store - * 在 SSR 应用中可用于在 setup 外使用 store + * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store + * @description 在 SSR 应用中可用于在 setup 外使用 store */ export function useAppStoreOutside() { return useAppStore(pinia) diff --git a/src/pinia/stores/permission.ts b/src/pinia/stores/permission.ts index 25512fe..aad4a4e 100644 --- a/src/pinia/stores/permission.ts +++ b/src/pinia/stores/permission.ts @@ -26,18 +26,18 @@ function filterDynamicRoutes(routes: RouteRecordRaw[], roles: string[]) { } export const usePermissionStore = defineStore("permission", () => { - /** 可访问的路由 */ + // 可访问的路由 const routes = ref([]) - /** 有访问权限的动态路由 */ + // 有访问权限的动态路由 const addRoutes = ref([]) - /** 根据角色生成可访问的 Routes(可访问的路由 = 常驻路由 + 有访问权限的动态路由) */ + // 根据角色生成可访问的 Routes(可访问的路由 = 常驻路由 + 有访问权限的动态路由) const setRoutes = (roles: string[]) => { const accessedRoutes = filterDynamicRoutes(dynamicRoutes, roles) _set(accessedRoutes) } - /** 所有路由 = 所有常驻路由 + 所有动态路由 */ + // 所有路由 = 所有常驻路由 + 所有动态路由 const setAllRoutes = () => { _set(dynamicRoutes) } @@ -51,8 +51,8 @@ export const usePermissionStore = defineStore("permission", () => { }) /** - * 在 SPA 应用中可用于在 pinia 实例被激活前使用 store - * 在 SSR 应用中可用于在 setup 外使用 store + * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store + * @description 在 SSR 应用中可用于在 setup 外使用 store */ export function usePermissionStoreOutside() { return usePermissionStore(pinia) diff --git a/src/pinia/stores/settings.ts b/src/pinia/stores/settings.ts index 2a717a7..0af615e 100644 --- a/src/pinia/stores/settings.ts +++ b/src/pinia/stores/settings.ts @@ -14,7 +14,7 @@ type SettingsStore = { type SettingsStoreKey = keyof SettingsStore export const useSettingsStore = defineStore("settings", () => { - /** 状态对象 */ + // 状态对象 const state = {} as SettingsStore // 遍历 layoutSettings 对象的键值对 for (const [key, value] of Object.entries(layoutSettings)) { @@ -29,7 +29,7 @@ export const useSettingsStore = defineStore("settings", () => { setConfigLayout(settings) }) } - /** 获取要缓存的数据:将 state 对象转化为 settings 对象 */ + // 获取要缓存的数据:将 state 对象转化为 settings 对象 const _getCacheData = () => { const settings = {} as LayoutSettings for (const [key, value] of Object.entries(state)) { @@ -43,8 +43,8 @@ export const useSettingsStore = defineStore("settings", () => { }) /** - * 在 SPA 应用中可用于在 pinia 实例被激活前使用 store - * 在 SSR 应用中可用于在 setup 外使用 store + * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store + * @description 在 SSR 应用中可用于在 setup 外使用 store */ export function useSettingsStoreOutside() { return useSettingsStore(pinia) diff --git a/src/pinia/stores/tags-view.ts b/src/pinia/stores/tags-view.ts index afaf588..1b4ee63 100644 --- a/src/pinia/stores/tags-view.ts +++ b/src/pinia/stores/tags-view.ts @@ -96,8 +96,8 @@ export const useTagsViewStore = defineStore("tags-view", () => { }) /** - * 在 SPA 应用中可用于在 pinia 实例被激活前使用 store - * 在 SSR 应用中可用于在 setup 外使用 store + * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store + * @description 在 SSR 应用中可用于在 setup 外使用 store */ export function useTagsViewStoreOutside() { return useTagsViewStore(pinia) diff --git a/src/pinia/stores/user.ts b/src/pinia/stores/user.ts index 3dfdff0..c10a528 100644 --- a/src/pinia/stores/user.ts +++ b/src/pinia/stores/user.ts @@ -17,20 +17,20 @@ export const useUserStore = defineStore("user", () => { const tagsViewStore = useTagsViewStore() const settingsStore = useSettingsStore() - /** 登录 */ + // 登录 const login = async ({ username, password, code }: LoginRequestData) => { const { data } = await loginApi({ username, password, code }) setToken(data.token) token.value = data.token } - /** 获取用户详情 */ + // 获取用户详情 const getInfo = async () => { const { data } = await getUserInfoApi() username.value = data.username // 验证返回的 roles 是否为一个非空数组,否则塞入一个没有任何作用的默认角色,防止路由守卫逻辑进入无限循环 roles.value = data.roles?.length > 0 ? data.roles : routeSettings.defaultRoles } - /** 模拟角色变化 */ + // 模拟角色变化 const changeRoles = async (role: string) => { const newToken = `token-${role}` token.value = newToken @@ -38,7 +38,7 @@ export const useUserStore = defineStore("user", () => { // 用刷新页面代替重新登录 window.location.reload() } - /** 登出 */ + // 登出 const logout = () => { removeToken() token.value = "" @@ -46,13 +46,13 @@ export const useUserStore = defineStore("user", () => { resetRouter() _resetTagsView() } - /** 重置 Token */ + // 重置 Token const resetToken = () => { removeToken() token.value = "" roles.value = [] } - /** 重置 Visited Views 和 Cached Views */ + // 重置 Visited Views 和 Cached Views const _resetTagsView = () => { if (!settingsStore.cacheTagsView) { tagsViewStore.delAllVisitedViews() @@ -64,8 +64,8 @@ export const useUserStore = defineStore("user", () => { }) /** - * 在 SPA 应用中可用于在 pinia 实例被激活前使用 store - * 在 SSR 应用中可用于在 setup 外使用 store + * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store + * @description 在 SSR 应用中可用于在 setup 外使用 store */ export function useUserStoreOutside() { return useUserStore(pinia) diff --git a/src/router/index.ts b/src/router/index.ts index 25ccef1..73f348b 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -6,8 +6,8 @@ import { flatMultiLevelRoutes, history } from "./helper" const Layouts = () => import("@/layouts/index.vue") /** - * 常驻路由 - * 除了 redirect/403/404/login 等隐藏页面,其他页面建议设置 Name 属性 + * @name 常驻路由 + * @description 除了 redirect/403/404/login 等隐藏页面,其他页面建议设置 Name 属性 */ export const constantRoutes: RouteRecordRaw[] = [ { @@ -252,9 +252,9 @@ export const constantRoutes: RouteRecordRaw[] = [ ] /** - * 动态路由 - * 用来放置有权限 (Roles 属性) 的路由 - * 必须带有 Name 属性 + * @name 动态路由 + * @description 用来放置有权限 (Roles 属性) 的路由 + * @description 必须带有 Name 属性 */ export const dynamicRoutes: RouteRecordRaw[] = [ { diff --git a/tsconfig.json b/tsconfig.json index 6f09e6c..f4b348e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,8 @@ -// https://www.typescriptlang.org/tsconfig -// https://cn.vuejs.org/guide/typescript/overview#configuring-tsconfig-json -// https://cn.vite.dev/guide/features#typescript-compiler-options +/** + * @link https://www.typescriptlang.org/tsconfig + * @link https://cn.vuejs.org/guide/typescript/overview#configuring-tsconfig-json + * @link https://cn.vite.dev/guide/features#typescript-compiler-options + */ { "compilerOptions": { diff --git a/types/vue-router.d.ts b/types/vue-router.d.ts index 1a86473..fa0f684 100644 --- a/types/vue-router.d.ts +++ b/types/vue-router.d.ts @@ -5,49 +5,49 @@ export {} declare module "vue-router" { interface RouteMeta { /** - * 设置该路由在侧边栏和面包屑中展示的名字 + * @description 设置该路由在侧边栏和面包屑中展示的名字 */ title?: string /** - * 设置该路由的图标,记得将 svg 导入 @/assets/icons + * @description 设置该路由的图标,记得将 svg 导入 @/assets/icons */ svgIcon?: string /** - * 设置该路由的图标,直接使用 Element Plus 的 Icon(与 svgIcon 同时设置时,svgIcon 将优先生效) + * @description 设置该路由的图标,直接使用 Element Plus 的 Icon(与 svgIcon 同时设置时,svgIcon 将优先生效) */ elIcon?: string /** - * 默认 false,设置 true 的时候该路由不会在侧边栏出现 + * @description 默认 false,设置 true 的时候该路由不会在侧边栏出现 */ hidden?: boolean /** - * 设置能进入该路由的角色,支持多个角色叠加 + * @description 设置能进入该路由的角色,支持多个角色叠加 */ roles?: string[] /** - * 默认 true,如果设置为 false,则不会在面包屑中显示 + * @description 默认 true,如果设置为 false,则不会在面包屑中显示 */ breadcrumb?: boolean /** - * 默认 false,如果设置为 true,它则会固定在 tags-view 中 + * @description 默认 false,如果设置为 true,它则会固定在 tags-view 中 */ affix?: boolean /** - * 当一个路由下面的 children 声明的路由大于 1 个时,自动会变成嵌套的模式, - * 只有一个时,会将那个子路由当做根路由显示在侧边栏, - * 若想不管路由下面的 children 声明的个数都显示你的根路由, - * 可以设置 alwaysShow: true,这样就会忽略之前定义的规则,一直显示根路由 + * @description 当一个路由下面的 children 声明的路由大于 1 个时,自动会变成嵌套的模式, + * @description 只有一个时,会将那个子路由当做根路由显示在侧边栏, + * @description 若想不管路由下面的 children 声明的个数都显示你的根路由, + * @description 可以设置 alwaysShow: true,这样就会忽略之前定义的规则,一直显示根路由 */ alwaysShow?: boolean /** - * 示例: activeMenu: "/xxx/xxx", - * 当设置了该属性进入路由时,则会高亮 activeMenu 属性对应的侧边栏。 - * 该属性适合使用在有 hidden: true 属性的路由上 + * @description 示例: activeMenu: "/xxx/xxx", + * @description 当设置了该属性进入路由时,则会高亮 activeMenu 属性对应的侧边栏。 + * @description 该属性适合使用在有 hidden: true 属性的路由上 */ activeMenu?: string /** - * 是否缓存该路由页面 - * 默认为 false,为 true 时代表需要缓存,此时该路由和该页面都需要设置一致的 Name + * @description 是否缓存该路由页面 + * @description 默认为 false,为 true 时代表需要缓存,此时该路由和该页面都需要设置一致的 Name */ keepAlive?: boolean } diff --git a/vite.config.ts b/vite.config.ts index 1341ed2..81506de 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -54,9 +54,9 @@ export default defineConfig(({ mode }) => { rollupOptions: { output: { /** - * 分块策略 - * 1. 注意这些包名必须存在,否则打包会报错 - * 2. 如果你不想自定义 chunk 分割策略,可以直接移除这段配置 + * @name 分块策略 + * @description 1. 注意这些包名必须存在,否则打包会报错 + * @description 2. 如果你不想自定义 chunk 分割策略,可以直接移除这段配置 */ manualChunks: { vue: ["vue", "vue-router", "pinia"],