diff --git a/vue-admin-wonderful-next/src/store/index.ts b/vue-admin-wonderful-next/src/store/index.ts index 67cf83f1..0d2a8613 100644 --- a/vue-admin-wonderful-next/src/store/index.ts +++ b/vue-admin-wonderful-next/src/store/index.ts @@ -31,6 +31,7 @@ export interface RootStateTypes { isTagsview: boolean, isBreadcrumbIcon: boolean, isTagsviewIcon: boolean, + isCacheTagsView: boolean, isFooter: boolean, isGrayscale: boolean, isInvert: boolean, diff --git a/vue-admin-wonderful-next/src/utils/themeConfig.ts b/vue-admin-wonderful-next/src/utils/themeConfig.ts index 8c32d38a..6f51cec7 100644 --- a/vue-admin-wonderful-next/src/utils/themeConfig.ts +++ b/vue-admin-wonderful-next/src/utils/themeConfig.ts @@ -28,6 +28,7 @@ export default { isTagsview: true, isBreadcrumbIcon: false, isTagsviewIcon: false, + isCacheTagsView: false, isFooter: false, isGrayscale: false, isInvert: false, diff --git a/vue-admin-wonderful-next/src/views/layout/navBars/breadcrumb/setings.vue b/vue-admin-wonderful-next/src/views/layout/navBars/breadcrumb/setings.vue index 65c14f24..7afbc70d 100644 --- a/vue-admin-wonderful-next/src/views/layout/navBars/breadcrumb/setings.vue +++ b/vue-admin-wonderful-next/src/views/layout/navBars/breadcrumb/setings.vue @@ -182,6 +182,12 @@ +
+
开启缓存 TagsView
+
+ +
+
开启 Footer
diff --git a/vue-admin-wonderful-next/src/views/layout/navBars/index.vue b/vue-admin-wonderful-next/src/views/layout/navBars/index.vue index 9230305c..7dc4794f 100644 --- a/vue-admin-wonderful-next/src/views/layout/navBars/index.vue +++ b/vue-admin-wonderful-next/src/views/layout/navBars/index.vue @@ -15,15 +15,12 @@ export default { components: { BreadcrumbIndex, TagsView }, setup() { const store = useStore(); - const getThemeConfig = computed(() => { - return store.state.themeConfig; - }); + // 是否显示 tagsView const setShowTagsView = computed(() => { let { layout } = store.state.themeConfig; return layout !== "classic"; }); return { - getThemeConfig, setShowTagsView, }; }, diff --git a/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/contextmenu.vue b/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/contextmenu.vue index ee18f5b8..01fb23b2 100644 --- a/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/contextmenu.vue +++ b/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/contextmenu.vue @@ -4,10 +4,12 @@ data-popper-placement="bottom" :style="`top: ${dropdown.y + 5}px;left: ${dropdown.x}px;`" :key="Math.random()" v-show="isShow">
@@ -35,26 +37,34 @@ export default defineComponent({ isShow: false, dropdownList: [ { id: 0, txt: "刷新", affix: false, icon: "el-icon-refresh-right" }, - { id: 1, txt: "关闭", affix: true, icon: "el-icon-close" }, + { id: 1, txt: "关闭", affix: false, icon: "el-icon-close" }, { id: 2, txt: "关闭其它", affix: false, icon: "el-icon-circle-close" }, { id: 3, txt: "全部关闭", affix: false, icon: "el-icon-folder-delete" }, ], }); + // 父级传过来的坐标 x,y 值 const dropdown = computed(() => { return props.dropdown; }); - const openContextmenu = () => { + // 打开右键菜单:判断是否固定,固定则不显示关闭按钮 + const openContextmenu = (meta: object) => { + meta.isAffix + ? (state.dropdownList[1].affix = true) + : (state.dropdownList[1].affix = false); closeContextmenu(); setTimeout(() => { state.isShow = true; }, 10); }; + // 关闭右键菜单 const closeContextmenu = () => { state.isShow = false; }; + // 监听页面监听进行右键菜单的关闭 onMounted(() => { document.body.addEventListener("click", closeContextmenu); }); + // 页面卸载时,移除右键菜单监听事件 onUnmounted(() => { document.body.removeEventListener("click", closeContextmenu); }); diff --git a/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/tagsView.vue b/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/tagsView.vue index fe6f795a..9b620407 100644 --- a/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/tagsView.vue +++ b/vue-admin-wonderful-next/src/views/layout/navBars/tagsView/tagsView.vue @@ -6,15 +6,15 @@
  • - + {{v.meta.title}} - +
  • @@ -31,10 +31,10 @@ import { ref, nextTick, onBeforeUpdate, - onBeforeMount, } from "vue"; import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router"; import { useStore } from "/@/store/index.ts"; +import { setSession, getSession } from "/@/utils/storage.ts"; import Sortable from "sortablejs"; import Contextmenu from "/@/views/layout/navBars/tagsView/contextmenu.vue"; import Scroll from "/@/views/layout/navBars/tagsView/scroll.vue"; @@ -57,6 +57,7 @@ export default { tagsRefsIndex: 0, tagsViewList: [], }); + // 动态设置 tagsView 风格样式 const setTagsStyle = computed(() => { let { tagsStyle } = store.state.themeConfig; if (tagsStyle === "tagsStyleTwo") return "layout-navbars-tagsview-ul-two"; @@ -65,44 +66,63 @@ export default { else if (tagsStyle === "tagsStyleFour") return "layout-navbars-tagsview-ul-four"; }); + // 获取布局配置信息 const getThemeConfig = computed(() => { return store.state.themeConfig; }); - // 设置/过滤路由(非静态路由/是否显示在菜单中) - const setFilterRoutes = () => { - console.log(store.state.tagsViewRoutes); - store.state.tagsViewRoutes.map((v) => { - if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v }); - }); + // 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录 + const addBrowserSetSession = () => { + setSession("tagsViewList", state.tagsViewList); }; - // 当前路由:未设置隐藏(isHide)也显示在 tagsView 中 + // vuex 中获取路由信息:如果是设置了固定的(isAffix),进行初始化显示 + const initTagsView = () => { + if ( + getSession("tagsViewList") && + store.state.themeConfig.isCacheTagsView + ) { + state.tagsViewList = getSession("tagsViewList"); + } else { + store.state.tagsViewRoutes.map((v) => { + if (v.meta.isAffix && !v.meta.isHide) + state.tagsViewList.push({ ...v }); + }); + addTagsView(route.path); + } + // 添加初始化横向滚动条移动到对应位置 + scrollRef.value.setScrollLeft(tagsRefs); + getTagsRefsIndex(route.path); + moveToCurrentTag(); + }; + // 添加 tagsView:未设置隐藏(isHide)也添加到在 tagsView 中 const addTagsView = (path: string) => { if (state.tagsViewList.some((v) => v.path === path)) return false; const item = store.state.tagsViewRoutes.find((v) => v.path === path); if (!item.meta.isHide) state.tagsViewList.push({ ...item }); + addBrowserSetSession(); }; - const initSortable = () => { - const el = document.querySelector(".layout-navbars-tagsview-ul"); - const sortable = Sortable.create(el, { animation: 300 }); - }; + // 判断页面高亮 const isActive = (path: string) => { return path === state.routePath; }; + // 右键点击时:传 x,y 坐标值到子组件中(props) const onContextmenu = (v: object, e: object) => { const { clientX, clientY } = e; state.dropdown.x = clientX; state.dropdown.y = clientY; - contextmenuRef.value.openContextmenu(); + contextmenuRef.value.openContextmenu(v.meta); }; + // 当前的 tagsView 项点击时 const onTagsClick = (v: object, k: number) => { state.tagsRefsIndex = k; router.push(v.path); }; + // tagsView 横向滚动 + 鼠标滚轮滚动 const moveToCurrentTag = () => { nextTick(() => { scrollRef.value.moveToTarget(tagsRefs.value[state.tagsRefsIndex]); }); }; + // 获取 tagsView 的下标:用于处理 tagsView 点击时的横向滚动 const getTagsRefsIndex = (path: string) => { if (state.tagsViewList.length > 0) { state.tagsRefsIndex = state.tagsViewList.findIndex( @@ -110,16 +130,19 @@ export default { ); } }; + // 设置 tagsView 可以进行拖拽 + const initSortable = () => { + const el = document.querySelector(".layout-navbars-tagsview-ul"); + const sortable = Sortable.create(el, { animation: 300 }); + }; + // 数据更新时 onBeforeUpdate(() => { tagsRefs.value = []; }); - onBeforeMount(() => { - setFilterRoutes(); - addTagsView(route.path); - }); + // 页面加载时 onMounted(() => { initSortable(); - scrollRef.value.setScrollLeft(tagsRefs); + initTagsView(); }); // 路由更新时 onBeforeRouteUpdate((to) => { @@ -180,7 +203,7 @@ export default { &-iconfont { position: relative; left: -5px; - font-size: 14px; + font-size: 12px; } &-icon { border-radius: 100%;