<template>
|
<div id="app">
|
<div v-if="$route.name == 'login'">
|
<router-view />
|
</div>
|
<div v-else>
|
<div id="appContainer">
|
<div class="left">
|
<Left ref="left" />
|
</div>
|
<div :class="isCollapse ? 'rightIsCollapse' : 'right'">
|
<Right ref="right" />
|
<keep-alive :include="caches">
|
<router-view style="height: calc(100vh - 140px);" />
|
</keep-alive>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
const debounce = (fn, delay) => {
|
let timer
|
return (...args) => {
|
if (timer) {
|
clearTimeout(timer)
|
}
|
timer = setTimeout(() => {
|
fn(...args)
|
}, delay)
|
}
|
}
|
const _ResizeObserver = window.ResizeObserver;
|
window.ResizeObserver = class ResizeObserver extends _ResizeObserver{
|
constructor(callback) {
|
callback = debounce(callback, 200);
|
super(callback);
|
}
|
}
|
|
import util from "./util";
|
import { mapActions } from "vuex";
|
import { mapState } from "vuex";
|
import Left from "@/components/Left.vue";
|
import Right from "@/components/Right.vue";
|
|
export default {
|
components: {
|
Left,
|
Right,
|
},
|
data() {
|
return {
|
isCollapse: false,
|
};
|
},
|
computed: {
|
...mapState("cache", ["caches"]),
|
...mapState(["isRenderTab"]),
|
},
|
watch: {
|
"$route.path": {
|
immediate: true,
|
handler() {
|
this.collectCaches();
|
},
|
},
|
},
|
mounted() {
|
var that = this;
|
util.$on("toggleIsCollapse", function (val) {
|
that.isCollapse = val;
|
});
|
},
|
methods: {
|
...mapActions("cache", ["addCache", "removeCache"]),
|
// 收集缓存(通过监听)
|
collectCaches() {
|
// 收集当前路由相关的缓存
|
this.$route.matched.forEach((routeMatch) => {
|
const instance = routeMatch.components.default;
|
const componentName = instance.name;
|
this.checkRouteComponentName(componentName, instance.__file);
|
// 配置了meta.keepAlive的路由组件添加到缓存
|
if (routeMatch.meta.keepAlive) {
|
if (!componentName) {
|
console.warn(`${routeMatch.path} 路由的组件名称name为空`);
|
return;
|
}
|
this.addCache(componentName);
|
} else {
|
this.removeCache(componentName);
|
}
|
});
|
},
|
// 检测路由组件名称是否重复
|
checkRouteComponentName(name, file) {
|
if (!this.cmpNames) this.cmpNames = {};
|
if (this.cmpNames[name]) {
|
if (this.cmpNames[name] !== file) {
|
console.warn(
|
`${file} 与${this.cmpNames[name]} 组件名称重复: ${name}`
|
);
|
}
|
} else {
|
this.cmpNames[name] = file;
|
}
|
},
|
},
|
};
|
</script>
|
|
<style lang="less">
|
.icon,
|
.iconfont {
|
font-family: "iconfont" !important;
|
font-size: 16px;
|
font-style: normal;
|
-webkit-font-smoothing: antialiased;
|
-webkit-text-stroke: 0.2px;
|
-moz-osx-font-smoothing: grayscale;
|
}
|
|
* {
|
margin: 0;
|
padding: 0;
|
}
|
|
body {
|
background-color: #f4f4f4;
|
color: #303133;
|
font-size: 14px;
|
}
|
|
#appContainer {
|
width: 100vw;
|
height: 100vh;
|
overflow: hidden;
|
display: flex;
|
|
.right {
|
width: calc(100vw - 207px);
|
}
|
|
.rightIsCollapse {
|
width: calc(100vw - 64px);
|
margin-right: -1px;
|
}
|
}
|
|
h2 {
|
margin-bottom: 18px;
|
}
|
|
.w220 {
|
width: 220px;
|
}
|
|
.wrap {
|
background-color: #fff;
|
padding: 10px;
|
}
|
|
.searchWrap {
|
display: flex;
|
justify-content: flex-start;
|
align-items: center;
|
|
.searchItem {
|
margin-right: 10px;
|
display: flex;
|
justify-content: flex-start;
|
align-items: center;
|
|
.searchTitle {
|
min-width: 56px;
|
margin-right: 10px;
|
color: #909399;
|
font-weight: bold;
|
}
|
}
|
|
.searchButton {
|
min-width: 150px;
|
}
|
}
|
|
.codeWrap {
|
width: 100vw;
|
height: 100vh;
|
background-color: rgba(0, 0, 0, .7);
|
position: fixed;
|
left: 0;
|
top: 0;
|
z-index: 999;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
|
.codeImg {
|
background-color: #fff;
|
padding: 20px;
|
}
|
|
.codeMessage {
|
margin-top: 20px;
|
font-size: 20px;
|
font-weight: bolder;
|
color: #fff;
|
}
|
}
|
|
.typeName {
|
background-color: #f5f7fa;
|
text-align: center;
|
border-radius: 4px;
|
}
|
|
.viewWrap {
|
padding: 20px;
|
display: flex;
|
flex-direction: column;
|
}
|
</style>
|