<template>
|
<div class="tabs-contain">
|
<div
|
class="tab-item active-tab"
|
v-if="currentPage && (currentPage != '/empty' || currentPage != '/')"
|
>
|
<div class="title">
|
{{ pageName(currentPage) }}
|
</div>
|
<i class="el-icon-close icon-close" @click="remove(currentPage)" />
|
</div>
|
<div class="others">
|
<div
|
:class="['posA', { 'left-shadow': !isLeft, 'right-shadow': !isEnd }]"
|
ref="container"
|
>
|
<div
|
class="inner"
|
ref="inner"
|
:style="{ transform: 'translateX(' + translateX + 'px)' }"
|
>
|
<div
|
class="tab-item"
|
v-for="(page, idx) in list"
|
:key="'list_' + idx"
|
>
|
<div class="title" @click="onTabClick(page)">
|
{{ pageName(page) }}
|
</div>
|
<i class="el-icon-close icon-close" @click="remove(page)" />
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="btn-grp" v-if="needScroll">
|
<div
|
:class="['btn', 'el-icon-caret-left', { disabled: isLeft }]"
|
@click="scrollLeft"
|
></div>
|
<div
|
:class="['btn', 'el-icon-caret-right', { disabled: isEnd }]"
|
@click="scrollRight"
|
></div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: "TabsBar",
|
props: {},
|
watch: {
|
$route(newRoute) {
|
this.activePage = newRoute.path;
|
// 判断是否需要缓存
|
if (this.checkCache(newRoute)) {
|
this.addCache(newRoute);
|
this.pageList.push(this.createPage(newRoute));
|
} else {
|
this.$store.dispatch("tagsView/updateVisitedViewName", newRoute);
|
}
|
},
|
},
|
computed: {
|
list() {
|
return this.pageList.filter(
|
(v) => v.path != this.activePage && v.path != "/" && v.path != "/empty"
|
);
|
},
|
currentPage() {
|
return this.pageList.filter(
|
(v) => v.path == this.activePage && v.path != "/" && v.path != "/empty"
|
)[0];
|
},
|
isLeft() {
|
return this.translateX == 0;
|
},
|
isEnd() {
|
this.needScroll;
|
let containerW = this.$refs.container
|
? this.$refs.container.clientWidth
|
: 0;
|
let innerW = this.$refs.inner ? this.$refs.inner.clientWidth : 0;
|
// console.log(this.translateX, containerW, innerW, '-=-==-=-=-=-');
|
return containerW >= innerW + this.translateX;
|
},
|
},
|
data() {
|
return {
|
pageList: [],
|
activePage: "",
|
needScroll: false,
|
translateX: 0,
|
};
|
},
|
components: {},
|
methods: {
|
checkCache(route) {
|
let { title } = this.createPage(route);
|
|
return this.$store.state.tagsView.cachedViews.indexOf(title) == -1;
|
},
|
addCache(route) {
|
let { title } = this.createPage(route);
|
this.$store.dispatch("tagsView/addView", { route, title });
|
},
|
createPage(route) {
|
return {
|
keyPath: route.matched[route.matched.length - 1].path,
|
fullPath: route.fullPath,
|
loading: false,
|
path: route.path,
|
name: route.name,
|
title: route.params && route.params.filename,
|
query: route.query,
|
params: route.params,
|
};
|
},
|
pageName(page) {
|
console.log(page, "pageName");
|
return page.title;
|
},
|
/**
|
* 添加监听器
|
*/
|
addListener() {
|
// window.addEventListener("page:close", this.closePageListener);
|
window.addEventListener("resize", this.checkScroll);
|
// window.addEventListener('page:refresh', this.refreshPageListener)
|
// window.addEventListener('unload', this.unloadListener)
|
},
|
/**
|
* 移出监听器
|
*/
|
removeListener() {
|
// window.removeEventListener("page:close", this.closePageListener);
|
window.removeEventListener("resize", this.checkScroll);
|
// window.removeEventListener('page:refresh', this.refreshPageListener)
|
// window.removeEventListener('unload', this.unloadListener)
|
},
|
/**
|
* 页签关闭事件监听
|
* @param event 页签关闭事件
|
*/
|
// closePageListener(event) {
|
// const { closeRoute, nextRoute } = event.detail;
|
// const closePath =
|
// typeof closeRoute === "string" ? closeRoute : closeRoute.path;
|
// const path = closePath && closePath.split("?")[0];
|
// this.remove(path, nextRoute);
|
// },
|
changePage(key) {
|
this.activePage = key;
|
const page = this.pageList.find((item) => item.path === key);
|
this.$router.push(page.fullPath);
|
},
|
remove(page) {
|
// if (this.pageList.length === 1) {
|
// return this.$message.warning('最后一个了');
|
// }
|
const { path, title } = page;
|
//清除缓存
|
this.$store.dispatch("tagsView/delView", title);
|
|
let index = this.pageList.findIndex((item) => item.path === path);
|
|
this.pageList.splice(index, 1);
|
if (path === this.activePage) {
|
index =
|
index >= this.pageList.length ? this.pageList.length - 1 : index;
|
this.activePage = this.pageList.length
|
? this.pageList[index].path
|
: "/";
|
const nextPage = this.pageList.length ? this.pageList[index] : {};
|
if ("result" == nextPage.name) {
|
this.$router.push({
|
path: "/result/" + nextPage.title,
|
query: nextPage.query,
|
});
|
} else {
|
this.$router.push(this.activePage);
|
}
|
}
|
this.checkScroll();
|
},
|
onTabClick(page) {
|
const { path, name, query, title } = page;
|
this.activePage = path;
|
// const page = this.pageList.find((item) => item.path === path);
|
if ("result" == name) {
|
this.$router.push({
|
path: "/result/" + title,
|
query,
|
});
|
} else {
|
this.$router.push(this.activePage);
|
}
|
},
|
// onClose(path) {
|
// this.pageList = this.pageList.filter((v) => v.path != path);
|
// this.activePage = this.pageList.length ? this.pageList[0].path : "";
|
// },
|
checkScroll() {
|
this.$nextTick(() => {
|
let container = this.$refs.container;
|
let inner = this.$refs.inner;
|
let containerW = container.clientWidth;
|
let innerW = inner.clientWidth;
|
this.needScroll = containerW < innerW;
|
if (this.translateX < 0 && containerW - this.translateX > innerW) {
|
this.translateX = containerW - innerW < 0 ? containerW - innerW : 0;
|
}
|
});
|
},
|
scrollLeft() {
|
if (this.isLeft) {
|
return false;
|
}
|
let innerW = this.$refs.inner.clientWidth;
|
let containerW = this.$refs.container.clientWidth;
|
let x = containerW > 600 ? containerW * 0.9 : containerW;
|
if (this.translateX + x >= 0) {
|
x = -this.translateX;
|
}
|
this.translateX += x;
|
},
|
scrollRight() {
|
if (this.isEnd) {
|
return false;
|
}
|
let containerW = this.$refs.container.clientWidth;
|
let innerW = this.$refs.inner.clientWidth;
|
let x = containerW > 600 ? containerW * 0.9 : containerW;
|
if (containerW - this.translateX + x > innerW) {
|
x = innerW + this.translateX - containerW;
|
}
|
this.translateX -= x;
|
},
|
},
|
|
mounted() {
|
this.addListener();
|
this.$bus.$on("checkScroll", this.checkScroll);
|
this.$bus.$on("closeFile", () => {
|
if (this.currentPage) {
|
this.remove(this.currentPage);
|
}
|
});
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.tabs-contain {
|
height: 32px;
|
box-shadow: 0 1px 4px -2px #333;
|
align-items: center;
|
background: #ddd;
|
display: flex;
|
.tab-item {
|
position: relative;
|
align-self: flex-end;
|
border: 1px solid #1aafea;
|
border-radius: 5px 5px 0 0;
|
padding: 6px 26px 0 4px;
|
cursor: pointer;
|
&.active-tab {
|
background: #1aafea;
|
}
|
.icon-close {
|
position: absolute;
|
width: 14px;
|
height: 14px;
|
font-size: 10px;
|
line-height: 14px;
|
text-align: center;
|
right: 4px;
|
top: 4px;
|
border-radius: 50%;
|
background: rgba(122, 122, 122, 0.6);
|
color: #fff;
|
&:hover {
|
background: rgba(255, 39, 39, 0.6);
|
}
|
}
|
}
|
.others {
|
flex: 1;
|
align-self: stretch;
|
position: relative;
|
.posA {
|
position: absolute;
|
left: 0;
|
right: 0;
|
top: 0;
|
bottom: 0;
|
overflow: hidden;
|
display: flex;
|
align-items: flex-end;
|
&.left-shadow::before {
|
content: "";
|
position: absolute;
|
left: 0;
|
top: 0;
|
bottom: 0;
|
box-shadow: 0 0 1px #333;
|
}
|
&.right-shadow::after {
|
content: "";
|
position: absolute;
|
right: 0;
|
top: 0;
|
bottom: 0;
|
box-shadow: 0 0 1px #333;
|
}
|
.inner {
|
white-space: nowrap;
|
text-align: left;
|
transition: transform 300ms;
|
.tab-item {
|
display: inline-block;
|
border: 1px #ccc solid;
|
min-width: 160px;
|
}
|
}
|
}
|
}
|
.btn-grp {
|
align-self: center;
|
.btn {
|
display: inline-block;
|
cursor: pointer;
|
font-size: 22px;
|
&.disabled {
|
background: #eee;
|
color: #aaa;
|
cursor: not-allowed;
|
}
|
}
|
}
|
}
|
</style>
|