diff --git a/package.json b/package.json index a35d9d7..41e8112 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "p": "plop" }, "dependencies": { - "@faker-js/faker": "^8.3.1", + "@faker-js/faker": "^8.4.0", "@iconify/iconify": "^3.1.1", "@iconify/vue": "^4.1.1", "@vueuse/core": "^10.7.2", @@ -34,13 +34,13 @@ "@wangeditor/editor-for-vue": "^5.1.10", "@zxcvbn-ts/core": "^3.0.4", "animate.css": "^4.1.1", - "axios": "^1.6.5", + "axios": "^1.6.7", "cropperjs": "^1.6.1", "dayjs": "^1.11.10", "driver.js": "^1.3.1", "echarts": "^5.4.3", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.5.3", + "element-plus": "2.5.5", "lodash-es": "^4.17.21", "mitt": "^3.0.1", "nprogress": "^0.2.0", @@ -49,64 +49,64 @@ "qrcode": "^1.5.3", "qs": "^6.11.2", "url": "^0.11.3", - "vue": "3.4.14", + "vue": "3.4.15", "vue-draggable-plus": "^0.3.5", - "vue-i18n": "9.9.0", + "vue-i18n": "9.9.1", "vue-json-pretty": "^2.3.0", "vue-router": "^4.2.5", "vue-types": "^5.1.1", - "xgplayer": "^3.0.11" + "xgplayer": "^3.0.12" }, "devDependencies": { - "@commitlint/cli": "^18.4.4", - "@commitlint/config-conventional": "^18.4.4", - "@iconify/json": "^2.2.169", + "@commitlint/cli": "^18.6.0", + "@commitlint/config-conventional": "^18.6.0", + "@iconify/json": "^2.2.180", "@intlify/unplugin-vue-i18n": "^2.0.0", "@types/fs-extra": "^11.0.4", "@types/inquirer": "^9.0.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.3", + "@types/node": "^20.11.16", "@types/nprogress": "^0.2.3", "@types/qrcode": "^1.5.5", "@types/qs": "^6.9.11", "@types/sortablejs": "^1.15.7", - "@typescript-eslint/eslint-plugin": "^6.19.0", - "@typescript-eslint/parser": "^6.19.0", - "@unocss/transformer-variant-group": "^0.58.3", - "@vitejs/plugin-legacy": "^5.2.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@unocss/transformer-variant-group": "^0.58.5", + "@vitejs/plugin-legacy": "^5.3.0", "@vitejs/plugin-vue": "^5.0.3", "@vitejs/plugin-vue-jsx": "^3.1.0", - "autoprefixer": "^10.4.16", + "autoprefixer": "^10.4.17", "chalk": "^5.3.0", "consola": "^3.2.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-define-config": "^2.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-vue": "^9.20.1", + "eslint-plugin-vue": "^9.21.1", "esno": "^4.0.0", "fs-extra": "^11.2.0", - "husky": "^8.0.3", - "inquirer": "^9.2.12", + "husky": "^9.0.10", + "inquirer": "^9.2.14", "less": "^4.2.0", - "lint-staged": "^15.2.0", + "lint-staged": "^15.2.2", "plop": "^4.0.1", - "postcss": "^8.4.33", + "postcss": "^8.4.34", "postcss-html": "^1.6.0", "postcss-less": "^6.0.0", - "prettier": "^3.2.2", + "prettier": "^3.2.5", "rimraf": "^5.0.5", - "rollup": "^4.9.5", + "rollup": "^4.9.6", "rollup-plugin-visualizer": "^5.12.0", - "stylelint": "^16.1.0", + "stylelint": "^16.2.1", "stylelint-config-html": "^1.1.0", "stylelint-config-recommended": "^14.0.0", "stylelint-config-standard": "^36.0.0", "stylelint-order": "^6.0.4", - "terser": "^5.26.0", + "terser": "^5.27.0", "typescript": "5.3.3", - "unocss": "^0.58.3", - "vite": "5.0.11", + "unocss": "^0.58.5", + "vite": "5.0.12", "vite-plugin-ejs": "^1.7.0", "vite-plugin-eslint": "^1.8.1", "vite-plugin-mock": "2.9.6", diff --git a/src/components/Menu/src/Menu.vue b/src/components/Menu/src/Menu.vue index e3448d6..1950824 100644 --- a/src/components/Menu/src/Menu.vue +++ b/src/components/Menu/src/Menu.vue @@ -89,11 +89,16 @@ export default defineComponent({ backgroundColor="var(--left-menu-bg-color)" textColor="var(--left-menu-text-color)" activeTextColor="var(--left-menu-text-active-color)" + popperClass={ + unref(menuMode) === 'vertical' + ? `${prefixCls}-popper--vertical` + : `${prefixCls}-popper--horizontal` + } onSelect={menuSelect} > {{ default: () => { - const { renderMenuItem } = useRenderMenuItem(unref(menuMode)) + const { renderMenuItem } = useRenderMenuItem() return renderMenuItem(unref(routers)) } }} @@ -123,30 +128,10 @@ export default defineComponent({ diff --git a/src/components/Menu/src/components/useRenderMenuItem.tsx b/src/components/Menu/src/components/useRenderMenuItem.tsx index 3a33922..301313f 100644 --- a/src/components/Menu/src/components/useRenderMenuItem.tsx +++ b/src/components/Menu/src/components/useRenderMenuItem.tsx @@ -2,57 +2,49 @@ import { ElSubMenu, ElMenuItem } from 'element-plus' import { hasOneShowingChild } from '../helper' import { isUrl } from '@/utils/is' import { useRenderMenuTitle } from './useRenderMenuTitle' -import { useDesign } from '@/hooks/web/useDesign' import { pathResolve } from '@/utils/routerHelper' const { renderMenuTitle } = useRenderMenuTitle() -export const useRenderMenuItem = ( +export const useRenderMenuItem = () => // allRouters: AppRouteRecordRaw[] = [], - menuMode: 'vertical' | 'horizontal' -) => { - const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => { - return routers - .filter((v) => !v.meta?.hidden) - .map((v) => { - const meta = v.meta ?? {} - const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v) - const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath(allRouters, v.path).join('/') + { + const renderMenuItem = (routers: AppRouteRecordRaw[], parentPath = '/') => { + return routers + .filter((v) => !v.meta?.hidden) + .map((v) => { + const meta = v.meta ?? {} + const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v) + const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath(allRouters, v.path).join('/') - if ( - oneShowingChild && - (!onlyOneChild?.children || onlyOneChild?.noShowingChildren) && - !meta?.alwaysShow - ) { - return ( - - {{ - default: () => renderMenuTitle(onlyOneChild ? onlyOneChild?.meta : meta) - }} - - ) - } else { - const { getPrefixCls } = useDesign() + if ( + oneShowingChild && + (!onlyOneChild?.children || onlyOneChild?.noShowingChildren) && + !meta?.alwaysShow + ) { + return ( + + {{ + default: () => renderMenuTitle(onlyOneChild ? onlyOneChild?.meta : meta) + }} + + ) + } else { + return ( + + {{ + title: () => renderMenuTitle(meta), + default: () => renderMenuItem(v.children!, fullPath) + }} + + ) + } + }) + } - const preFixCls = getPrefixCls('menu-popper') - return ( - - {{ - title: () => renderMenuTitle(meta), - default: () => renderMenuItem(v.children!, fullPath) - }} - - ) - } - }) + return { + renderMenuItem + } } - - return { - renderMenuItem - } -} diff --git a/src/components/Menu/src/helper.ts b/src/components/Menu/src/helper.ts index b483881..003cf10 100644 --- a/src/components/Menu/src/helper.ts +++ b/src/components/Menu/src/helper.ts @@ -1,4 +1,3 @@ -import type { RouteMeta } from 'vue-router' import { ref, unref } from 'vue' import { findPath } from '@/utils/tree' @@ -21,7 +20,7 @@ export const hasOneShowingChild = ( const onlyOneChild = ref() const showingChildren = children.filter((v) => { - const meta = (v.meta ?? {}) as RouteMeta + const meta = v.meta ?? {} if (meta.hidden) { return false } else { diff --git a/src/components/TabMenu/src/TabMenu.vue b/src/components/TabMenu/src/TabMenu.vue index 4b12a46..8642a3c 100644 --- a/src/components/TabMenu/src/TabMenu.vue +++ b/src/components/TabMenu/src/TabMenu.vue @@ -204,7 +204,8 @@ export default defineComponent({ { '!left-[var(--tab-menu-min-width)]': unref(collapse), '!left-[var(--tab-menu-max-width)]': !unref(collapse), - '!w-[calc(var(--left-menu-max-width)+1px)]': unref(showMenu) || unref(fixedMenu), + '!w-[var(--left-menu-max-width)] border-r-1 border-r-solid border-[var(--el-border-color)]': + unref(showMenu) || unref(fixedMenu), '!w-0': !unref(showMenu) && !unref(fixedMenu) } ]} diff --git a/src/components/Table/src/components/TableActions.vue b/src/components/Table/src/components/TableActions.vue index 2eaab32..c62cb48 100644 --- a/src/components/Table/src/components/TableActions.vue +++ b/src/components/Table/src/components/TableActions.vue @@ -7,11 +7,6 @@ import { useAppStore } from '@/store/modules/app' import { TableColumn } from '../types' import ColumnSetting from './ColumnSetting.vue' -const appStore = useAppStore() -const sizeMap = computed(() => appStore.sizeMap) - -const { t } = useI18n() - export default defineComponent({ name: 'TableActions', components: { @@ -25,6 +20,9 @@ export default defineComponent({ }, emits: ['refresh', 'changSize', 'confirm'], setup(props, { emit }) { + const appStore = useAppStore() + const { t } = useI18n() + const sizeMap = computed(() => appStore.sizeMap) const showSetting = ref(false) const refresh = () => { diff --git a/src/components/TagsView/src/TagsView.vue b/src/components/TagsView/src/TagsView.vue index 3eb2d98..b4876c5 100644 --- a/src/components/TagsView/src/TagsView.vue +++ b/src/components/TagsView/src/TagsView.vue @@ -12,6 +12,8 @@ import { useDesign } from '@/hooks/web/useDesign' import { useTemplateRefsList } from '@vueuse/core' import { ElScrollbar } from 'element-plus' import { useScrollTo } from '@/hooks/event/useScrollTo' +import { useTagsView } from '@/hooks/web/useTagsView' +import { cloneDeep } from 'lodash-es' const { getPrefixCls } = useDesign() @@ -19,7 +21,9 @@ const prefixCls = getPrefixCls('tags-view') const { t } = useI18n() -const { currentRoute, push, replace } = useRouter() +const { currentRoute, push } = useRouter() + +const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTagsView() const permissionStore = usePermissionStore() @@ -31,6 +35,10 @@ const visitedViews = computed(() => tagsViewStore.getVisitedViews) const affixTagArr = ref([]) +const selectedTag = computed(() => tagsViewStore.getSelectedTag) + +const setSelectTag = tagsViewStore.setSelectedTag + const appStore = useAppStore() const tagsViewIcon = computed(() => appStore.getTagsViewIcon) @@ -43,66 +51,30 @@ const initTags = () => { for (const tag of unref(affixTagArr)) { // Must have tag name if (tag.name) { - tagsViewStore.addVisitedView(tag) + tagsViewStore.addVisitedView(cloneDeep(tag)) } } } -const selectedTag = ref() - // 新增tag const addTags = () => { const { name } = unref(currentRoute) if (name) { - selectedTag.value = unref(currentRoute) + setSelectTag(unref(currentRoute)) tagsViewStore.addView(unref(currentRoute)) } - return false } // 关闭选中的tag const closeSelectedTag = (view: RouteLocationNormalizedLoaded) => { - if (view?.meta?.affix) return - tagsViewStore.delView(view) - if (isActive(view)) { - toLastView() - } -} - -// 关闭全部 -const closeAllTags = () => { - tagsViewStore.delAllViews() - toLastView() -} - -// 关闭其它 -const closeOthersTags = () => { - tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded) -} - -// 重新加载 -const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => { - if (!view) return - tagsViewStore.delCachedView() - const { path, query } = view - await nextTick() - replace({ - path: '/redirect' + path, - query: query + closeCurrent(view, () => { + if (isActive(view)) { + toLastView() + } }) } -// 关闭左侧 -const closeLeftTags = () => { - tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded) -} - -// 关闭右侧 -const closeRightTags = () => { - tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded) -} - -// 跳转到最后一个 +// 去最后一个 const toLastView = () => { const visitedViews = tagsViewStore.getVisitedViews const latestView = visitedViews.slice(-1)[0] @@ -121,6 +93,33 @@ const toLastView = () => { } } +// 关闭全部 +const closeAllTags = () => { + closeAll(() => { + toLastView() + }) +} + +// 关闭其它 +const closeOthersTags = () => { + closeOther() +} + +// 重新加载 +const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => { + refreshPage(view) +} + +// 关闭左侧 +const closeLeftTags = () => { + closeLeft() +} + +// 关闭右侧 +const closeRightTags = () => { + closeRight() +} + // 滚动到选中的tag const moveToCurrentTag = async () => { await nextTick() @@ -211,13 +210,14 @@ const isActive = (route: RouteLocationNormalizedLoaded): boolean => { // 所有右键菜单组件的元素 const itemRefs = useTemplateRefsList>() -// 右键菜单装填改变的时候 +// 右键菜单状态改变的时候 const visibleChange = (visible: boolean, tagItem: RouteLocationNormalizedLoaded) => { if (visible) { for (const v of unref(itemRefs)) { const elDropdownMenuRef = v.elDropdownMenuRef if (tagItem.fullPath !== v.tagItem.fullPath) { elDropdownMenuRef?.handleClose() + setSelectTag(tagItem) } } } diff --git a/src/hooks/web/useTagsView.ts b/src/hooks/web/useTagsView.ts new file mode 100644 index 0000000..31eadb0 --- /dev/null +++ b/src/hooks/web/useTagsView.ts @@ -0,0 +1,63 @@ +import { useTagsViewStoreWithOut } from '@/store/modules/tagsView' +import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router' +import { computed, nextTick, unref } from 'vue' + +export const useTagsView = () => { + const tagsViewStore = useTagsViewStoreWithOut() + + const { replace, currentRoute } = useRouter() + + const selectedTag = computed(() => tagsViewStore.getSelectedTag) + + const closeAll = (callback?: Fn) => { + tagsViewStore.delAllViews() + callback?.() + } + + const closeLeft = (callback?: Fn) => { + tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded) + callback?.() + } + + const closeRight = (callback?: Fn) => { + tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded) + callback?.() + } + + const closeOther = (callback?: Fn) => { + tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded) + callback?.() + } + + const closeCurrent = (view?: RouteLocationNormalizedLoaded, callback?: Fn) => { + if (view?.meta?.affix) return + tagsViewStore.delView(view || unref(currentRoute)) + + callback?.() + } + + const refreshPage = async (view?: RouteLocationNormalizedLoaded, callback?: Fn) => { + tagsViewStore.delCachedView() + const { path, query } = view || unref(currentRoute) + await nextTick() + replace({ + path: '/redirect' + path, + query: query + }) + callback?.() + } + + const setTitle = (title: string, path?: string) => { + tagsViewStore.setTitle(title, path) + } + + return { + closeAll, + closeLeft, + closeRight, + closeOther, + closeCurrent, + refreshPage, + setTitle + } +}