mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-11-04 10:57:08 +08:00 
			
		
		
		
	feat: tab栏增加右键菜单
Closes #IA5RD4
This commit is contained in:
		@@ -15,25 +15,71 @@
 | 
				
			|||||||
        :title="(item.meta?.title as string)"
 | 
					        :title="(item.meta?.title as string)"
 | 
				
			||||||
        :closable="Boolean(!item.meta?.affix)"
 | 
					        :closable="Boolean(!item.meta?.affix)"
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
      </a-tab-pane>
 | 
					        <template #title>
 | 
				
			||||||
      <template #extra>
 | 
					          <a-dropdown trigger="contextMenu">
 | 
				
			||||||
        <a-dropdown trigger="hover">
 | 
					            <span @contextmenu="(e) => handleContextMenu(e, item.path)">
 | 
				
			||||||
          <MagicIcon class="gi_mr"></MagicIcon>
 | 
					              {{ item.meta?.title }}
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <template #content>
 | 
					            <template #content>
 | 
				
			||||||
            <a-doption @click="tabsStore.closeCurrent(route.path)">
 | 
					              <a-doption @click="tabsStore.closeCurrent(currentContextPath)">
 | 
				
			||||||
              <template #icon><icon-close /></template>
 | 
					                <template #icon>
 | 
				
			||||||
 | 
					                  <icon-close />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
                <template #default>关闭当前</template>
 | 
					                <template #default>关闭当前</template>
 | 
				
			||||||
              </a-doption>
 | 
					              </a-doption>
 | 
				
			||||||
            <a-doption @click="tabsStore.closeRight(route.path)">
 | 
					              <a-doption @click="tabsStore.closeRight(currentContextPath)">
 | 
				
			||||||
              <template #icon><icon-close /></template>
 | 
					                <template #icon>
 | 
				
			||||||
 | 
					                  <icon-close />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
                <template #default>关闭右侧</template>
 | 
					                <template #default>关闭右侧</template>
 | 
				
			||||||
              </a-doption>
 | 
					              </a-doption>
 | 
				
			||||||
            <a-doption @click="tabsStore.closeOther(route.path)">
 | 
					              <a-doption @click="tabsStore.closeOther(currentContextPath)">
 | 
				
			||||||
              <template #icon><icon-eraser /></template>
 | 
					                <template #icon>
 | 
				
			||||||
 | 
					                  <icon-eraser />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
                <template #default>关闭其他</template>
 | 
					                <template #default>关闭其他</template>
 | 
				
			||||||
              </a-doption>
 | 
					              </a-doption>
 | 
				
			||||||
              <a-doption @click="tabsStore.closeAll">
 | 
					              <a-doption @click="tabsStore.closeAll">
 | 
				
			||||||
              <template #icon><icon-minus /></template>
 | 
					                <template #icon>
 | 
				
			||||||
 | 
					                  <icon-minus />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #default>关闭全部</template>
 | 
				
			||||||
 | 
					              </a-doption>
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					          </a-dropdown>
 | 
				
			||||||
 | 
					        </template>
 | 
				
			||||||
 | 
					      </a-tab-pane>
 | 
				
			||||||
 | 
					      <template #extra>
 | 
				
			||||||
 | 
					        <a-dropdown trigger="hover">
 | 
				
			||||||
 | 
					          <a-button type="text">
 | 
				
			||||||
 | 
					            <template #icon>
 | 
				
			||||||
 | 
					              <icon-more-vertical />
 | 
				
			||||||
 | 
					            </template>
 | 
				
			||||||
 | 
					          </a-button>
 | 
				
			||||||
 | 
					          <template #content>
 | 
				
			||||||
 | 
					            <a-doption @click="tabsStore.closeCurrent(route.path)">
 | 
				
			||||||
 | 
					              <template #icon>
 | 
				
			||||||
 | 
					                <icon-close />
 | 
				
			||||||
 | 
					              </template>
 | 
				
			||||||
 | 
					              <template #default>关闭当前</template>
 | 
				
			||||||
 | 
					            </a-doption>
 | 
				
			||||||
 | 
					            <a-doption @click="tabsStore.closeRight(route.path)">
 | 
				
			||||||
 | 
					              <template #icon>
 | 
				
			||||||
 | 
					                <icon-close />
 | 
				
			||||||
 | 
					              </template>
 | 
				
			||||||
 | 
					              <template #default>关闭右侧</template>
 | 
				
			||||||
 | 
					            </a-doption>
 | 
				
			||||||
 | 
					            <a-doption @click="tabsStore.closeOther(route.path)">
 | 
				
			||||||
 | 
					              <template #icon>
 | 
				
			||||||
 | 
					                <icon-eraser />
 | 
				
			||||||
 | 
					              </template>
 | 
				
			||||||
 | 
					              <template #default>关闭其他</template>
 | 
				
			||||||
 | 
					            </a-doption>
 | 
				
			||||||
 | 
					            <a-doption @click="tabsStore.closeAll">
 | 
				
			||||||
 | 
					              <template #icon>
 | 
				
			||||||
 | 
					                <icon-minus />
 | 
				
			||||||
 | 
					              </template>
 | 
				
			||||||
              <template #default>关闭全部</template>
 | 
					              <template #default>关闭全部</template>
 | 
				
			||||||
            </a-doption>
 | 
					            </a-doption>
 | 
				
			||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
@@ -45,30 +91,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import type { RouteLocationNormalized } from 'vue-router'
 | 
					import type { RouteLocationNormalized } from 'vue-router'
 | 
				
			||||||
import MagicIcon from './MagicIcon.vue'
 | 
					 | 
				
			||||||
import { useAppStore, useTabsStore } from '@/stores'
 | 
					import { useAppStore, useTabsStore } from '@/stores'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'Tabs' })
 | 
					defineOptions({ name: 'Tabs' })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const route = useRoute()
 | 
					const route = useRoute()
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
const appStore = useAppStore()
 | 
					const appStore = useAppStore()
 | 
				
			||||||
const tabsStore = useTabsStore()
 | 
					const tabsStore = useTabsStore()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 重置, 同时把 affix: true 的路由筛选出来
 | 
					// 菜单获取的路径
 | 
				
			||||||
 | 
					const currentContextPath = ref('')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Initialize tabs
 | 
				
			||||||
tabsStore.init()
 | 
					tabsStore.init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 路由发生改变触发
 | 
					 | 
				
			||||||
const handleRouteChange = () => {
 | 
					const handleRouteChange = () => {
 | 
				
			||||||
  const item = { ...route } as unknown as RouteLocationNormalized
 | 
					  const item = { ...route } as unknown as RouteLocationNormalized
 | 
				
			||||||
  tabsStore.addTabItem(toRaw(item))
 | 
					  tabsStore.addTabItem(toRaw(item))
 | 
				
			||||||
  tabsStore.addCacheItem(toRaw(item))
 | 
					  tabsStore.addCacheItem(toRaw(item))
 | 
				
			||||||
  // console.log('路由对象', toRaw(item))
 | 
					 | 
				
			||||||
  // console.log('tagList', toRaw(tabsStore.tabList))
 | 
					 | 
				
			||||||
  // console.log('cacheList', toRaw(tabsStore.cacheList))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
handleRouteChange()
 | 
					handleRouteChange()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 监听路由变化
 | 
					 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => route.fullPath,
 | 
					  () => route.fullPath,
 | 
				
			||||||
  () => {
 | 
					  () => {
 | 
				
			||||||
@@ -76,27 +121,33 @@ watch(
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 点击页签
 | 
					const handleTabClick = (key: string | number) => {
 | 
				
			||||||
const handleTabClick = (key: string) => {
 | 
					 | 
				
			||||||
  const obj = tabsStore.tabList.find((i) => i.path === key)
 | 
					  const obj = tabsStore.tabList.find((i) => i.path === key)
 | 
				
			||||||
  obj ? router.push(obj.fullPath || obj.path) : router.push(key)
 | 
					  obj ? router.push(obj.fullPath || obj.path) : router.push(String(key))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const handleContextMenu = (e: MouseEvent, path: string) => {
 | 
				
			||||||
 | 
					  if (!path) return
 | 
				
			||||||
 | 
					  e.preventDefault()
 | 
				
			||||||
 | 
					  currentContextPath.value = path
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
:deep(.arco-tabs-nav-tab) {
 | 
					:deep(.arco-tabs-nav-tab) {
 | 
				
			||||||
  .arco-tabs-tab {
 | 
					  .arco-tabs-tab {
 | 
				
			||||||
    border-bottom-color: transparent !important;
 | 
					 | 
				
			||||||
    svg {
 | 
					    svg {
 | 
				
			||||||
      width: 0;
 | 
					      width: 0;
 | 
				
			||||||
      transition: all 0.15s;
 | 
					      transition: all 0.15s;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &:hover {
 | 
					    &:hover {
 | 
				
			||||||
      svg {
 | 
					      svg {
 | 
				
			||||||
        width: 1em;
 | 
					        width: 1em;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:not(.arco-tabs-nav-tab-scroll) {
 | 
					  &:not(.arco-tabs-nav-tab-scroll) {
 | 
				
			||||||
    .arco-tabs-tab:first-child {
 | 
					    .arco-tabs-tab:first-child {
 | 
				
			||||||
      border-left: 0;
 | 
					      border-left: 0;
 | 
				
			||||||
@@ -111,5 +162,6 @@ const handleTabClick = (key: string) => {
 | 
				
			|||||||
.tabs {
 | 
					.tabs {
 | 
				
			||||||
  padding-top: 5px;
 | 
					  padding-top: 5px;
 | 
				
			||||||
  background-color: var(--color-bg-1);
 | 
					  background-color: var(--color-bg-1);
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user