perf: perf

This commit is contained in:
xiaoxian521
2021-04-19 18:11:12 +08:00
parent d6fcab53b9
commit fdff569de9
26 changed files with 287 additions and 134 deletions

View File

@@ -10,7 +10,7 @@
</section>
</template>
<script>
<script lang="ts">
import { computed, defineComponent } from "vue";
import { useRoute } from "vue-router";
export default defineComponent({
@@ -20,7 +20,7 @@ export default defineComponent({
const key = computed(() => route.path);
return { key };
},
}
});
</script>

View File

@@ -9,20 +9,21 @@
<Breadcrumb class="breadcrumb-container" />
<div class="right-menu">
<!-- 全屏 -->
<screenfull />
<!-- 国际化 -->
<div class="inter" :title="langs ? '中文' : '英文'" @click="toggleLang">
<img :src="langs ? ch : en" />
</div>
<el-dropdown>
<!-- 退出登陆 -->
<el-dropdown trigger="click">
<span class="el-dropdown-link">
<img :src="favicon" />
<p>{{ usename }}</p>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item icon="el-icon-switch-button" @click="logout">
{{ $t("LoginOut") }}
</el-dropdown-item>
<el-dropdown-item icon="el-icon-switch-button" @click="logout">{{ $t("LoginOut") }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -48,7 +49,7 @@ export default defineComponent({
components: {
Breadcrumb,
Hamburger,
screenfull,
screenfull
},
setup() {
let langs = ref(true);
@@ -95,7 +96,7 @@ export default defineComponent({
en,
favicon
};
},
}
});
</script>
@@ -149,13 +150,11 @@ export default defineComponent({
display: flex;
align-items: center;
justify-content: space-around;
margin-right: 20px;
margin-right: 10px;
cursor: pointer;
p {
font-size: 13px;
}
&:hover {
background: #f0f0f0;
}
img {
width: 22px;
height: 22px;

View File

@@ -15,7 +15,7 @@
import { useFullscreen } from '@vueuse/core'
import {
defineComponent,
} from "vue";
} from "vue"
export default defineComponent({
name: "screenfull",
setup() {
@@ -24,7 +24,7 @@ export default defineComponent({
return {
isFullscreen,
toggle,
};
}
},
});
</script>

View File

@@ -10,6 +10,10 @@
<span>色弱模式</span>
<vxe-switch v-model="weekVal" open-label="开" close-label="关" @change="weekChange"></vxe-switch>
</li>
<li>
<span>隐藏标签页</span>
<vxe-switch v-model="tagsVal" open-label="开" close-label="关" @change="tagsChange"></vxe-switch>
</li>
</ul>
</panel>
</template>
@@ -19,6 +23,7 @@ import panel from "../panel/index.vue";
import { onMounted, reactive, toRefs } from "vue";
import { storageLocal } from "/@/utils/storage";
import { toggleClass } from "/@/utils/operate";
import { emitter } from "/@/utils/mitt";
export default {
name: "setting",
@@ -39,7 +44,8 @@ export default {
const settings = reactive({
greyVal: storageLocal.getItem("greyVal"),
weekVal: storageLocal.getItem("weekVal")
weekVal: storageLocal.getItem("weekVal"),
tagsVal: storageLocal.getItem("tagsVal")
});
settings.greyVal === null
@@ -74,11 +80,20 @@ export default {
: localOperate("weekVal", false, "set");
};
const tagsChange = () => {
let showVal = settings.tagsVal;
showVal
? storageLocal.setItem("tagsVal", true)
: storageLocal.setItem("tagsVal", false);
emitter.emit("tagViewsChange", showVal);
};
return {
...toRefs(settings),
localOperate,
greyChange,
weekChange
weekChange,
tagsChange
};
}
};

View File

@@ -1,5 +1,5 @@
<template>
<div class="tags-view">
<div class="tags-view" v-if="!showTags">
<el-scrollbar :vertical="false" class="scroll-container">
<div
v-for="(item, index) in dynamicTagList"
@@ -10,16 +10,23 @@
<span v-if="index !== 0 " class="el-icon-close" @click="deleteMenu(item)"></span>
</div>
</el-scrollbar>
<slot></slot>
</div>
</template>
<script>
import { useDynamicRoutesHook } from "./tagsHook"
import { useRoute } from "vue-router"
import { ref, watchEffect } from "vue"
import { useRoute, useRouter } from "vue-router"
import { ref, watchEffect, onBeforeMount, unref } from "vue"
import { storageLocal } from "/@/utils/storage"
import { emitter } from "/@/utils/mitt"
export default {
setup() {
const route = useRoute()
const router = useRouter()
const showTags = ref(storageLocal.getItem("tagsVal") || false)
const { deleteDynamicTag, dRoutes } = ref(useDynamicRoutesHook()).value
function deleteMenu(item) {
@@ -39,9 +46,17 @@ export default {
stop()
})
onBeforeMount(() => {
emitter.on("tagViewsChange", (key) => {
if (unref(showTags) === key) return
showTags.value = key
})
})
return {
dynamicTagList: dRoutes,
deleteMenu,
showTags
}
},
};
@@ -55,7 +70,7 @@ export default {
display: flex;
align-items: center;
justify-content: flex-start;
margin-left: 5px;
position: relative;
.scroll-item {
border-radius: 3px;
padding: 2px 8px;
@@ -64,27 +79,34 @@ export default {
a {
text-decoration: none;
color: #666;
padding: 0 4px 0 10px;
padding: 0 4px 0 4px;
}
.scroll-container {
text-align: left;
padding: 5px 0;
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
background: #fff;
border: 0.5px solid rgba($color: #ccc, $alpha: 0.3);
.scroll-item {
&:nth-child(1) {
margin-left: 5px;
}
}
}
}
.el-icon-close {
cursor: pointer;
border-radius: 50%;
padding: 1px;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.el-icon-close:hover {
background: #b4bccc;
}
.scroll-container {
text-align: left;
padding: 5px 0;
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
}
.active {
background: #409eff;
position: relative;
@@ -93,17 +115,7 @@ export default {
color: #fff;
}
}
.active::before {
content: "";
background: #fff;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 50%;
left: 5px;
margin-top: -4px;
margin-right: 2px;
:deep(.el-scrollbar__wrap) {
height: 100vh;
}
</style>

View File

@@ -1,4 +1,5 @@
import { reactive, toRefs, nextTick } from "vue"
import { storageLocal } from "/@/utils/storage"
import { useRouter } from "vue-router"
interface InterDynamic {
@@ -25,10 +26,11 @@ export function useDynamicRoutesHook() {
* @param value string 当前menu对应的路由path
* @param parentPath string 当前路由中父级路由
*/
function dynamicRouteTags(value: string, parentPath: string): void {
const dynamicRouteTags = (value: string, parentPath: string): void => {
const hasValue = dynamic.dRoutes.some((item: any) => {
return item.path === value
})
function concatPath(arr: object[], value: string, parentPath: string) {
if (!hasValue) {
arr.forEach((arrItem: any) => {
@@ -45,6 +47,14 @@ export function useDynamicRoutesHook() {
}
}
concatPath(router.options.routes, value, parentPath)
if (storageLocal.getItem("routesInStorage") && storageLocal.getItem("routesInStorage").length > 2) {
let lens = storageLocal.getItem("routesInStorage").length
let itemss = storageLocal.getItem("routesInStorage")[lens - 1]
dynamic.dRoutes.push({ path: itemss.path, meta: itemss.meta })
}
storageLocal.setItem("routesInStorage", dynamic.dRoutes)
}
/**
* @param value any 当前删除tag路由
@@ -56,6 +66,7 @@ export function useDynamicRoutesHook() {
})
// 从当前匹配到的路径中删除
await dynamic.dRoutes.splice(valueIndex, 1)
storageLocal.setItem("routesInStorage", dynamic.dRoutes)
if (current === obj.path) { // 如果删除当前激活tag就自动切换到最后一个tag
let newRoute: any = dynamic.dRoutes.slice(-1)
nextTick(() => {

View File

@@ -6,13 +6,29 @@
@click="handleClickOutside"
/>
<!-- 侧边栏 -->
<sidebar class="sidebar-container" />
<sidebar class="sidebar-container" v-if="!containerHiddenSideBar" />
<div class="main-container">
<div :class="{ 'fixed-header': fixedHeader }">
<!-- 顶部导航栏 -->
<navbar />
<navbar v-if="!containerHiddenSideBar" />
<!-- tabs标签页 -->
<tag />
<tag>
<!-- 右侧功能按钮 -->
<ul class="right-func">
<li>
<i class="el-icon-refresh-right"></i>
</li>
<li>
<i class="el-icon-arrow-down"></i>
</li>
<li>
<i
:class="containerHiddenSideBar? 'iconfont team-iconhidden-main-container': 'iconfont team-iconshow-main-container'"
@click="onFullScreen"
></i>
</li>
</ul>
</tag>
</div>
<!-- 主体内容 -->
<app-main />
@@ -26,17 +42,23 @@
import { Navbar, Sidebar, AppMain, setting, tag } from "./components";
import {
ref,
unref,
reactive,
computed,
toRefs,
watch,
nextTick,
watchEffect,
onMounted,
onBeforeMount,
onBeforeUnmount,
onBeforeUnmount
} from "vue";
import { useStore } from "vuex";
import { useEventListener } from "@vueuse/core";
import { useEventListener, useFullscreen } from "@vueuse/core";
import { toggleClass } from "/@/utils/operate";
let hiddenMainContainer = "hidden-main-container";
import options from "/@/settings";
interface setInter {
sidebar: any;
device: String;
@@ -58,6 +80,8 @@ export default {
const WIDTH = ref(992);
let containerHiddenSideBar = ref(options.hiddenSideBar);
const set: setInter = reactive({
sidebar: computed(() => {
return store.state.app.sidebar;
@@ -76,17 +100,17 @@ export default {
hideSidebar: !set.sidebar.opened,
openSidebar: set.sidebar.opened,
withoutAnimation: set.sidebar.withoutAnimation,
mobile: set.device === "mobile",
mobile: set.device === "mobile"
};
}),
})
});
watchEffect(() => {
if (set.device === "mobile" && !set.sidebar.opened) {
store.dispatch("app/closeSideBar", { withoutAnimation: false });
}
})
});
const handleClickOutside = () => {
store.dispatch("app/closeSideBar", { withoutAnimation: false });
};
@@ -107,23 +131,48 @@ export default {
}
};
function onFullScreen() {
if (unref(containerHiddenSideBar)) {
containerHiddenSideBar.value = false;
toggleClass(
false,
hiddenMainContainer,
document.querySelector(".main-container")
);
} else {
containerHiddenSideBar.value = true;
toggleClass(
true,
hiddenMainContainer,
document.querySelector(".main-container")
);
}
}
onMounted(() => {
const isMobile = $_isMobile();
if (isMobile) {
store.dispatch("app/toggleDevice", "mobile");
store.dispatch("app/closeSideBar", { withoutAnimation: true });
}
toggleClass(
unref(containerHiddenSideBar),
hiddenMainContainer,
document.querySelector(".main-container")
);
});
onBeforeMount(() => {
useEventListener("resize", $_resizeHandler);
});
return {
...toRefs(set),
handleClickOutside,
containerHiddenSideBar,
onFullScreen
};
},
}
};
</script>
@@ -173,4 +222,23 @@ $sideBarWidth: 210px;
.mobile .fixed-header {
width: 100%;
}
.right-func {
display: flex;
align-items: center;
background: #fff;
border: 0.5px solid rgba($color: #ccc, $alpha: 0.3);
font-size: 16px;
li {
width: 40px;
height: 34px;
line-height: 34px;
text-align: center;
border-right: 1px solid #ccc;
cursor: pointer;
}
}
.hidden-main-container {
margin-left: 0 !important;
}
</style>