|
@@ -0,0 +1,132 @@
|
|
|
+<template>
|
|
|
+ <div class="_tagList">
|
|
|
+ <div class="tag-view">
|
|
|
+ <ul>
|
|
|
+ <li v-for="(item, index) in visitedViews" :key="index">
|
|
|
+ <router-link :to="{ ...item }" custom v-slot="{ navigate }" v-if="index != 0">
|
|
|
+ <el-tag
|
|
|
+ @click="navigate"
|
|
|
+ class="mx-1"
|
|
|
+ closable
|
|
|
+ :disable-transitions="false"
|
|
|
+ @close="closeSelectedTag(item, index)"
|
|
|
+ >
|
|
|
+ {{ item.meta.title }}
|
|
|
+ </el-tag>
|
|
|
+ </router-link>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script setup lang="ts">
|
|
|
+import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import { usePermissionStore } from '@/store/modules/permission'
|
|
|
+import { useTagsViewStore } from '@/store/modules/tagsView'
|
|
|
+import { filterAffixTags } from './helper'
|
|
|
+const selectedTag = ref<RouteLocationNormalizedLoaded>()
|
|
|
+const { currentRoute, push, replace } = useRouter()
|
|
|
+const permissionStore = usePermissionStore()
|
|
|
+const routers = computed(() => permissionStore.getRouters)
|
|
|
+const tagsViewStore = useTagsViewStore()
|
|
|
+const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
|
|
|
+
|
|
|
+const visitedViews = computed(() => tagsViewStore.getVisitedViews)
|
|
|
+// 初始化tag
|
|
|
+const initTags = () => {
|
|
|
+ affixTagArr.value = filterAffixTags(unref(routers))
|
|
|
+
|
|
|
+ for (const tag of unref(affixTagArr)) {
|
|
|
+ // Must have tag name
|
|
|
+ if (tag.name) {
|
|
|
+ tagsViewStore.addVisitedView(tag)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增tag
|
|
|
+const addTags = () => {
|
|
|
+ const { name } = unref(currentRoute)
|
|
|
+ if (name) {
|
|
|
+ selectedTag.value = 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()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 是否是当前tag
|
|
|
+const isActive = (route: RouteLocationNormalizedLoaded): boolean => {
|
|
|
+ return route.path === unref(currentRoute).path
|
|
|
+}
|
|
|
+
|
|
|
+// 跳转到最后一个
|
|
|
+const toLastView = () => {
|
|
|
+ const visitedViews = tagsViewStore.getVisitedViews
|
|
|
+ const latestView = visitedViews.slice(-1)[0]
|
|
|
+ if (latestView) {
|
|
|
+ push(latestView)
|
|
|
+ } else {
|
|
|
+ if (
|
|
|
+ unref(currentRoute).path === permissionStore.getAddRouters[0].path ||
|
|
|
+ unref(currentRoute).path === permissionStore.getAddRouters[0].redirect
|
|
|
+ ) {
|
|
|
+ addTags()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // TODO: You can set another route
|
|
|
+ push('/')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => currentRoute.value,
|
|
|
+ () => {
|
|
|
+ addTags()
|
|
|
+ }
|
|
|
+)
|
|
|
+/** 初始化 **/
|
|
|
+onMounted(() => {
|
|
|
+ initTags()
|
|
|
+ addTags()
|
|
|
+})
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+div,
|
|
|
+h1,
|
|
|
+h2,
|
|
|
+h3,
|
|
|
+h4,
|
|
|
+h5,
|
|
|
+h6,
|
|
|
+p,
|
|
|
+ul,
|
|
|
+li {
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+._tagList {
|
|
|
+ width: 100%;
|
|
|
+ height: 35px;
|
|
|
+ border-bottom: 1px solid red;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 10px;
|
|
|
+ .tag-view {
|
|
|
+ ul {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ li {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|