update
This commit is contained in:
parent
e570a7e509
commit
f4eaebdb41
@ -12,6 +12,6 @@ $subMenuBg: #1f2d3d; // 子菜单背景颜色
|
|||||||
$subMenuHover: #001528; // 鼠标经过子菜单时的背景颜色
|
$subMenuHover: #001528; // 鼠标经过子菜单时的背景颜色
|
||||||
$collapseMenuActiveBg: #1f2d3d; // 菜单宽度折叠后,已选中菜单的背景颜色
|
$collapseMenuActiveBg: #1f2d3d; // 菜单宽度折叠后,已选中菜单的背景颜色
|
||||||
$collapseMenuActiveColor: $menuTextColor; // 菜单宽度折叠后,已选中菜单的文字颜色
|
$collapseMenuActiveColor: $menuTextColor; // 菜单宽度折叠后,已选中菜单的文字颜色
|
||||||
$collapseMenuActiveBorderBg: $mainColor; // 菜单宽度折叠后,已选中菜单的边框颜色
|
$collapseMenuActiveBorderColor: $mainColor; // 菜单宽度折叠后,已选中菜单的边框颜色
|
||||||
$collapseMenuActiveBorderWidth: 2px; // 菜单宽度折叠后,已选中菜单的边框宽度
|
$collapseMenuActiveBorderWidth: 2px; // 菜单宽度折叠后,已选中菜单的边框宽度
|
||||||
$arrowColor: #909399; // 展开/收起箭头颜色
|
$arrowColor: #909399; // 展开/收起箭头颜色
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
42
src/layout/components/Content/index.vue
Normal file
42
src/layout/components/Content/index.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
|
||||||
|
<keep-alive :include="cacheList">
|
||||||
|
<component
|
||||||
|
:is="Component"
|
||||||
|
:key="key"
|
||||||
|
/>
|
||||||
|
</keep-alive>
|
||||||
|
|
||||||
|
</router-view>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { computed, defineComponent } from "vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const store = useStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const cacheList = computed(() => store.state.tags.cacheList);
|
||||||
|
const key = computed(() => route.path);
|
||||||
|
|
||||||
|
return {
|
||||||
|
cacheList,
|
||||||
|
key,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
background: #f0f2f5;
|
||||||
|
padding: 16px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -92,7 +92,7 @@ export default defineComponent({
|
|||||||
top: 0;
|
top: 0;
|
||||||
width: $collapseMenuActiveBorderWidth;
|
width: $collapseMenuActiveBorderWidth;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: $collapseMenuActiveBorderBg;
|
background-color: $collapseMenuActiveBorderColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="tabs"></div>
|
|
||||||
</template>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.tabs {
|
|
||||||
height: 32px;
|
|
||||||
border-bottom: 1px solid #eaeaea;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
26
src/layout/components/Tagsbar/ScrollBar.vue
Normal file
26
src/layout/components/Tagsbar/ScrollBar.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<el-scrollbar
|
||||||
|
ref="scrollContainer"
|
||||||
|
:vertical="false"
|
||||||
|
class="scroll-container"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</el-scrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.scroll-container {
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
::v-deep(.el-scrollbar__bar) {
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
::v-deep(.el-scrollbar__wrap) {
|
||||||
|
height: 49px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
327
src/layout/components/Tagsbar/index.vue
Normal file
327
src/layout/components/Tagsbar/index.vue
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
id="tags-view-container"
|
||||||
|
class="tags-view-container"
|
||||||
|
>
|
||||||
|
<scroll-bar
|
||||||
|
ref="scrollBar"
|
||||||
|
class="tags-view-wrapper"
|
||||||
|
@scroll="handleScroll"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
v-for="tag in tagList"
|
||||||
|
ref="tags"
|
||||||
|
:key="tag.path"
|
||||||
|
:class="isActive(tag)?'active':''"
|
||||||
|
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||||
|
tag="span"
|
||||||
|
class="tags-view-item"
|
||||||
|
@click.middle="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||||
|
@contextmenu.prevent="openMenu(tag,$event)"
|
||||||
|
>
|
||||||
|
{{ tag.title }}
|
||||||
|
<span
|
||||||
|
v-if="!isAffix(tag)"
|
||||||
|
class="el-icon-refresh"
|
||||||
|
@click.prevent.stop="refreshSelectedTag(tag)"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="!isAffix(tag)"
|
||||||
|
class="el-icon-close"
|
||||||
|
@click.prevent.stop="closeSelectedTag(tag)"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
</scroll-bar>
|
||||||
|
<ul
|
||||||
|
v-show="visible"
|
||||||
|
:style="{left:left+'px',top:top+'px'}"
|
||||||
|
class="contextmenu"
|
||||||
|
>
|
||||||
|
<li @click="refreshSelectedTag(selectedTag)">刷新</li>
|
||||||
|
<li
|
||||||
|
v-if="!isAffix(selectedTag)"
|
||||||
|
@click="closeSelectedTag(selectedTag)"
|
||||||
|
>关闭</li>
|
||||||
|
<li @click="closeOthersTags">关闭其他</li>
|
||||||
|
<li @click="closeAllTags(selectedTag)">关闭全部</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ScrollBar from "./ScrollBar.vue";
|
||||||
|
import path from "path";
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
defineComponent,
|
||||||
|
reactive,
|
||||||
|
watch,
|
||||||
|
toRefs,
|
||||||
|
onMounted,
|
||||||
|
onBeforeUnmount,
|
||||||
|
ref,
|
||||||
|
nextTick,
|
||||||
|
} from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "Tagsbar",
|
||||||
|
components: { ScrollBar },
|
||||||
|
setup() {
|
||||||
|
const store = useStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const route = router.currentRoute;
|
||||||
|
|
||||||
|
const tags = ref(null);
|
||||||
|
const scrollBar = ref(null);
|
||||||
|
|
||||||
|
const tagList = computed(() => store.state.tags.tagList);
|
||||||
|
const routes = computed(() => router.getRoutes());
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
visible: false,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
selectedTag: {},
|
||||||
|
affixTags: [],
|
||||||
|
isReload: false,
|
||||||
|
isActive(tag) {
|
||||||
|
return tag.path === route.value.path;
|
||||||
|
},
|
||||||
|
isAffix(tag) {
|
||||||
|
return !!tag.meta && !!tag.meta.affix;
|
||||||
|
},
|
||||||
|
filterAffixTags(routes) {
|
||||||
|
return routes.filter((route) => !!route.meta && !!route.meta.affix);
|
||||||
|
},
|
||||||
|
initTags() {
|
||||||
|
const affixTags = (state.affixTags = state.filterAffixTags(
|
||||||
|
routes.value
|
||||||
|
));
|
||||||
|
for (const tag of affixTags) {
|
||||||
|
// Must have tag name
|
||||||
|
if (!!tag.name) {
|
||||||
|
store.dispatch("tags/addTagList", tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeTag(tag) {
|
||||||
|
store.dispatch("tags/delTag", tag);
|
||||||
|
},
|
||||||
|
addTags() {
|
||||||
|
if (route.value.name) {
|
||||||
|
store.dispatch("tags/addTag", route.value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
saveActivePosition(oldRoute) {
|
||||||
|
const index = tagList.value.findIndex(
|
||||||
|
(item) => item.fullPath === oldRoute.fullPath
|
||||||
|
);
|
||||||
|
|
||||||
|
store.dispatch("tags/saveActivePosition", Math.max(0, index));
|
||||||
|
},
|
||||||
|
moveToCurrentTag(callback) {
|
||||||
|
nextTick(() => {
|
||||||
|
for (const tag of tagList.value) {
|
||||||
|
if (tag.path === route.value.path) {
|
||||||
|
// scrollBar.value.moveToTarget(tag);
|
||||||
|
|
||||||
|
if (tag.fullPath !== route.value.fullPath) {
|
||||||
|
store.dispatch("tags/updateTagList", route.value);
|
||||||
|
}
|
||||||
|
callback && callback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reload() {
|
||||||
|
// this.refreshSelectedTag(this.$route)
|
||||||
|
state.isReload = true;
|
||||||
|
},
|
||||||
|
refreshSelectedTag(tag) {
|
||||||
|
store.dispatch("tags/delCacheList", tag).then(() => {
|
||||||
|
const { fullPath } = tag;
|
||||||
|
nextTick(() => {
|
||||||
|
router.replace({
|
||||||
|
path: "/redirect" + fullPath,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
closeSelectedTag(tag) {
|
||||||
|
const closedTagIndex = tagList.value.findIndex(
|
||||||
|
(item) => item.fullPath === tag.fullPath
|
||||||
|
);
|
||||||
|
store.dispatch("tags/delTag", tag).then(({ tagList }) => {
|
||||||
|
if (state.isActive(tag)) {
|
||||||
|
state.toLastView(tagList, tag, closedTagIndex - 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
closeOthersTags() {
|
||||||
|
router.push(state.selectedTag);
|
||||||
|
store.dispatch("tags/delOtherTags", state.selectedTag).then(() => {
|
||||||
|
state.moveToCurrentTag();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
closeAllTags(view) {
|
||||||
|
const closedTagIndex = tagList.value.findIndex(
|
||||||
|
(item) => item.fullPath === view.fullPath
|
||||||
|
);
|
||||||
|
store.dispatch("tags/delAllTags").then(({ tagList }) => {
|
||||||
|
if (state.affixTags.some((tag) => tag.path === view.path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.toLastView(tagList, view, closedTagIndex - 1);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toLastView(tagList, view, lastTagIndex) {
|
||||||
|
const lastTag = tagList[lastTagIndex];
|
||||||
|
if (!!lastTag) {
|
||||||
|
router.push(lastTag.fullPath);
|
||||||
|
} else {
|
||||||
|
router.push("/");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openMenu(tag, e) {
|
||||||
|
state.left = e.clientX;
|
||||||
|
state.top = e.clientY;
|
||||||
|
state.visible = true;
|
||||||
|
state.selectedTag = tag;
|
||||||
|
},
|
||||||
|
closeMenu() {
|
||||||
|
state.visible = false;
|
||||||
|
},
|
||||||
|
handleScroll() {
|
||||||
|
state.closeMenu();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(route, (newRoute, oldRoute) => {
|
||||||
|
console.log("监听路由", newRoute, oldRoute);
|
||||||
|
state.saveActivePosition(oldRoute); // 保存上一个tag页签的位置
|
||||||
|
state.addTags();
|
||||||
|
state.moveToCurrentTag(() => {
|
||||||
|
if (state.isReload) {
|
||||||
|
state.isReload = false;
|
||||||
|
state.refreshSelectedTag(this.$route);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
state.initTags();
|
||||||
|
state.addTags();
|
||||||
|
document.addEventListener("click", state.closeMenu);
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
document.removeEventListener("click", state.closeMenu);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
tagList,
|
||||||
|
routes,
|
||||||
|
tags,
|
||||||
|
scrollBar,
|
||||||
|
...toRefs(state),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tags-view-container {
|
||||||
|
height: 34px;
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #d8dce5;
|
||||||
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
|
||||||
|
.tags-view-wrapper {
|
||||||
|
.tags-view-item {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 31px;
|
||||||
|
border-left: 1px solid #e6e6e6;
|
||||||
|
border-right: 1px solid #e6e6e6;
|
||||||
|
color: #5c5c5c;
|
||||||
|
background: #fff;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: -1px;
|
||||||
|
&:first-of-type {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
&:last-of-type {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
background-color: #f6f7f6;
|
||||||
|
color: #333;
|
||||||
|
border-color: #f6f7f6;
|
||||||
|
border-top: 2px solid #333;
|
||||||
|
border-left: 1px solid #e6e6e6;
|
||||||
|
// &::before {
|
||||||
|
// content: '';
|
||||||
|
// width: 8px;
|
||||||
|
// height: 8px;
|
||||||
|
// position: relative;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contextmenu {
|
||||||
|
margin: 0;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 3000;
|
||||||
|
position: absolute;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 5px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #333;
|
||||||
|
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 7px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
//reset element css of el-icon-close
|
||||||
|
.tags-view-wrapper {
|
||||||
|
.tags-view-item {
|
||||||
|
.el-icon-close,
|
||||||
|
.el-icon-refresh {
|
||||||
|
margin-left: 2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
vertical-align: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||||
|
transform-origin: 100% 50%;
|
||||||
|
&:before {
|
||||||
|
transform: scale(0.8);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -2px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -14,18 +14,13 @@
|
|||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { defineComponent, ref, onBeforeMount, watch } from "vue";
|
||||||
defineComponent,
|
import { useRouter } from "vue-router";
|
||||||
ref,
|
|
||||||
onBeforeMount,
|
|
||||||
getCurrentInstance,
|
|
||||||
watch,
|
|
||||||
} from "vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const { ctx } = getCurrentInstance();
|
const router = useRouter();
|
||||||
const route = ctx.$router.currentRoute; // 这里不使用useRoute获取当前路由,否则下面watch监听路由的时候会有警告
|
const route = router.currentRoute; // 这里不使用useRoute获取当前路由,否则下面watch监听路由的时候会有警告
|
||||||
const breadcrumbs = ref([]);
|
const breadcrumbs = ref([]);
|
||||||
|
|
||||||
const getBreadcrumbs = (route) => {
|
const getBreadcrumbs = (route) => {
|
||||||
|
|||||||
@ -4,11 +4,9 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<topbar />
|
<topbar />
|
||||||
<tabsbar />
|
<tagsbar />
|
||||||
</div>
|
|
||||||
<div class="main">
|
|
||||||
<router-view />
|
|
||||||
</div>
|
</div>
|
||||||
|
<content />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -16,13 +14,15 @@
|
|||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import Sidebar from "./components/Sidebar/index.vue";
|
import Sidebar from "./components/Sidebar/index.vue";
|
||||||
import Topbar from "./components/Topbar/index.vue";
|
import Topbar from "./components/Topbar/index.vue";
|
||||||
import Tabsbar from "./components/Tabsbar/index.vue";
|
import Tagsbar from "./components/Tagsbar/index.vue";
|
||||||
|
import Content from "./components/Content/index.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
Topbar,
|
Topbar,
|
||||||
Tabsbar,
|
Tagsbar,
|
||||||
|
Content,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -39,12 +39,6 @@ export default defineComponent({
|
|||||||
.top {
|
.top {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
.main {
|
|
||||||
flex: 1;
|
|
||||||
background: #f0f2f5;
|
|
||||||
padding: 16px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -7,7 +7,7 @@ import home from './modules/home'
|
|||||||
import test from './modules/test'
|
import test from './modules/test'
|
||||||
|
|
||||||
|
|
||||||
// 左侧菜单(左侧菜单请配置在此,否则无法显示)
|
// 左侧菜单
|
||||||
export const allMenus = [
|
export const allMenus = [
|
||||||
...home,
|
...home,
|
||||||
...test,
|
...test,
|
||||||
|
|||||||
@ -3,11 +3,13 @@ import { createStore } from "vuex";
|
|||||||
import app from "./modules/app";
|
import app from "./modules/app";
|
||||||
import account from "./modules/account";
|
import account from "./modules/account";
|
||||||
import menu from "./modules/menu";
|
import menu from "./modules/menu";
|
||||||
|
import tags from "./modules/tags";
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
modules: {
|
modules: {
|
||||||
app,
|
app,
|
||||||
account,
|
account,
|
||||||
menu
|
menu,
|
||||||
|
tags
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
153
src/store/modules/tags.js
Normal file
153
src/store/modules/tags.js
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
const state = {
|
||||||
|
tagList: [],
|
||||||
|
cacheList: [],
|
||||||
|
activePosition: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
ADD_TAG_LIST: (state, tag) => {
|
||||||
|
if (state.tagList.some(v => v.path === tag.path)) return;
|
||||||
|
state.tagList.splice(
|
||||||
|
state.activePosition + 1,
|
||||||
|
0,
|
||||||
|
Object.assign({}, tag, {
|
||||||
|
title: tag.meta.title || 'no-name'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
},
|
||||||
|
ADD_CACHE_LIST: (state, tag) => {
|
||||||
|
if (state.cacheList.includes(tag.name)) return
|
||||||
|
if (!tag.meta.noCache) {
|
||||||
|
state.cacheList.push(tag.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DEL_TAG_LIST: (state, tag) => {
|
||||||
|
state.tagList = state.tagList.filter(v => v.path !== tag.path)
|
||||||
|
},
|
||||||
|
DEL_CACHE_LIST: (state, tag) => {
|
||||||
|
state.cacheList = state.cacheList.filter(v => v !== tag.name)
|
||||||
|
},
|
||||||
|
|
||||||
|
DEL_OTHER_TAG_LIST: (state, tag) => {
|
||||||
|
state.tagList = state.tagList.filter(v => !!v.meta.affix || v.path === tag.path)
|
||||||
|
},
|
||||||
|
DEL_OTHER_CACHE_LIST: (state, tag) => {
|
||||||
|
state.cacheList = state.cacheList.filter(v => v === tag.name)
|
||||||
|
},
|
||||||
|
|
||||||
|
DEL_ALL_TAG_LIST: state => {
|
||||||
|
state.tagList = state.tagList.filter(v => !!v.meta.affix)
|
||||||
|
},
|
||||||
|
DEL_ALL_CACHE_LIST: state => {
|
||||||
|
state.cacheList = []
|
||||||
|
},
|
||||||
|
|
||||||
|
UPDATE_TAG_LIST: (state, tag) => {
|
||||||
|
const index = state.tagList.findIndex(v => v.path === tag.path);
|
||||||
|
if (index > -1) {
|
||||||
|
state.tagList[index] = Object.assign({}, tag)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
SAVE_ACTIVE_POSITION: (state, index) => {
|
||||||
|
state.activePosition = index
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
saveActivePosition ({ commit }, index) {
|
||||||
|
commit('SAVE_ACTIVE_POSITION', index)
|
||||||
|
},
|
||||||
|
addTag ({ dispatch }, tag) {
|
||||||
|
dispatch('addTagList', tag)
|
||||||
|
dispatch('addCacheList', tag)
|
||||||
|
},
|
||||||
|
addTagList ({ commit }, tag) {
|
||||||
|
commit('ADD_TAG_LIST', tag)
|
||||||
|
},
|
||||||
|
addCacheList ({ commit }, tag) {
|
||||||
|
commit('ADD_CACHE_LIST', tag)
|
||||||
|
},
|
||||||
|
|
||||||
|
delTag ({ dispatch, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dispatch('delTagList', tag)
|
||||||
|
dispatch('delCacheList', tag)
|
||||||
|
resolve({
|
||||||
|
tagList: [...state.tagList],
|
||||||
|
cacheList: [...state.cacheList]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delTagList ({ commit, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_TAG_LIST', tag)
|
||||||
|
resolve([...state.tagList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delCacheList ({ commit, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_CACHE_LIST', tag)
|
||||||
|
resolve([...state.cacheList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
delOtherTags ({ dispatch, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dispatch('delOtherTagList', tag)
|
||||||
|
dispatch('delOtherCacheList', tag)
|
||||||
|
resolve({
|
||||||
|
tagList: [...state.tagList],
|
||||||
|
cacheList: [...state.cacheList]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delOtherTagList ({ commit, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_OTHER_TAG_LIST', tag)
|
||||||
|
resolve([...state.tagList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delOtherCacheList ({ commit, state }, tag) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_OTHER_CACHE_LIST', tag)
|
||||||
|
resolve([...state.cacheList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
delAllTags ({ dispatch, state }) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dispatch('delAllTagList')
|
||||||
|
dispatch('delAllCacheList')
|
||||||
|
resolve({
|
||||||
|
tagList: [...state.tagList],
|
||||||
|
cacheList: [...state.cacheList]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delAllTagList ({ commit, state }) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_ALL_TAG_LIST')
|
||||||
|
resolve([...state.tagList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delAllCacheList ({ commit, state }) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
commit('DEL_ALL_CACHE_LIST')
|
||||||
|
resolve([...state.cacheList])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
updateTagList ({ commit }, tag) {
|
||||||
|
commit('UPDATE_TAG_LIST', tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
||||||
@ -2,27 +2,24 @@
|
|||||||
<div class="error">
|
<div class="error">
|
||||||
<template v-if="error === '403'">
|
<template v-if="error === '403'">
|
||||||
<span class="code-403">403</span>
|
<span class="code-403">403</span>
|
||||||
<img
|
<svg-icon
|
||||||
src="~@/assets/error-icons/403.svg"
|
name="error-icons-403"
|
||||||
alt=""
|
|
||||||
class="error-img"
|
class="error-img"
|
||||||
>
|
/>
|
||||||
<h2 class="title">您无权访问此页面</h2>
|
<h2 class="title">您无权访问此页面</h2>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="error === '500'">
|
<template v-else-if="error === '500'">
|
||||||
<img
|
<svg-icon
|
||||||
src="~@/assets/error-icons/500.svg"
|
name="error-icons-500"
|
||||||
alt=""
|
|
||||||
class="error-img"
|
class="error-img"
|
||||||
>
|
/>
|
||||||
<h2 class="title">服务器出错了</h2>
|
<h2 class="title">服务器出错了</h2>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="error === '404'">
|
<template v-else-if="error === '404'">
|
||||||
<img
|
<svg-icon
|
||||||
src="~@/assets/error-icons/404.svg"
|
name="error-icons-404"
|
||||||
alt=""
|
|
||||||
class="error-img"
|
class="error-img"
|
||||||
>
|
/>
|
||||||
<h2 class="title">您访问的页面不存在</h2>
|
<h2 class="title">您访问的页面不存在</h2>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -66,7 +63,7 @@ export default defineComponent({
|
|||||||
color: #ee5c42;
|
color: #ee5c42;
|
||||||
}
|
}
|
||||||
.error-img {
|
.error-img {
|
||||||
width: 320px;
|
font-size: 320px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user