使用vue + jquery 的方法实现
通过计算当前显示的tab累计宽度,设置margin-left实现左右切换
<div class="tabs-menu">
<div class="pre" :class="classObj" @click="scrollTabLeft()">
<img :src="arrowLeft">
</div>
<div class="next" @click="scrollTabRight()">
<img :src="arrowRight">
</div>
<div class="menuTabs">
<div class="page-tabs-content">
<router-link class="menuTab" v-for="tag in visitedViews" ref="tag" :key="tag.path" :class="isActive(tag)?'active':''" :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" tag="span" :style="activeStyle(tag)" @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" @contextmenu.prevent.native="openMenu(tag,$event)">
{{ tag.title }}
<span v-if="!isAffix(tag)" class="el-icon-close close" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</div>
</div>
</div>
function calSumWidth(elements) {
var width = 0;
$(elements).each(function () {
width += $(this).outerWidth(true);
});
return width;
}
export default {
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: [],
arrowRight: arrowRight,
arrowLeft: arrowLeft,
}
},
computed: {
...mapState({
sidebar: state => state.app.sidebar,
}),
classObj() {
return {
isHide: !this.sidebar.opened,
isShow: this.sidebar.opened,
}
},
},
mounted() {
this.initTags()
this.addTags();
},
methods: {
scrollTabLeft() {
var marginLeftVal = Math.abs(parseInt($('.page-tabs-content').css('margin-left')));
var tabOuterWidth = calSumWidth($(".tabs-menu").children().not(".menuTabs"));
var visibleWidth = $(".tabs-menu").outerWidth(true) - tabOuterWidth;
var scrollVal = 0;
if (($(".page-tabs-content").width()) < visibleWidth) {
return false;
} else {
var tabElement = $(".menuTab:first");
var offsetVal = 0;
while ((offsetVal + $(tabElement).outerWidth(true)) <= marginLeftVal) {
offsetVal += $(tabElement).outerWidth(true);
tabElement = $(tabElement).next();
}
offsetVal = 0;
if (calSumWidth($(tabElement).prevAll()) > visibleWidth) {
while ((offsetVal + $(tabElement).outerWidth(true)) < (visibleWidth) && tabElement.length > 0) {
offsetVal += $(tabElement).outerWidth(true);
tabElement = $(tabElement).prev();
}
scrollVal = calSumWidth($(tabElement).prevAll());
}
}
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
},
scrollTabRight() {
var marginLeftVal = Math.abs(parseInt($('.page-tabs-content').css('margin-left')));
var tabOuterWidth = calSumWidth($(".tabs-menu").children().not(".menuTabs"));
var visibleWidth = $(".tabs-menu").outerWidth(true) - tabOuterWidth;
var scrollVal = 0;
if ($(".page-tabs-content").width() < visibleWidth) {
return false;
} else {
var tabElement = $(".menuTab:first");
var offsetVal = 0;
while ((offsetVal + $(tabElement).outerWidth(true)) <= marginLeftVal) {
offsetVal += $(tabElement).outerWidth(true);
tabElement = $(tabElement).next();
}
offsetVal = 0;
while ((offsetVal + $(tabElement).outerWidth(true)) < (visibleWidth) && tabElement.length > 0) {
offsetVal += $(tabElement).outerWidth(true);
tabElement = $(tabElement).next();
}
scrollVal = calSumWidth($(tabElement).prevAll());
if (scrollVal > 0) {
$('.page-tabs-content').animate({
marginLeft: 0 - scrollVal + 'px'
},
"fast");
}
}
},
isActive(route) {
return route.path === this.$route.path
},
isAffix(tag) {
return tag.meta && tag.meta.affix
},
activeStyle(tag) {
if (!this.isActive(tag)) return {};
return {
"color": this.theme
};
},
}
}
@import "@/assets/styles/variables.scss";
.tabs-menu {
height: 40px;
.pre,
.next {
z-index: 1001;
position: fixed;
top: 64px;
width: 28px;
height: 40px;
line-height: 40px;
border: 1px solid rgba(222, 223, 225, 0.4);
background-color: #fff;
text-align: center;
cursor: pointer;
img {
width: 25px;
height: 25px;
vertical-align: middle;
opacity: 0.8;
}
}
.pre:hover,
.next:hover {
background-color: #f2f2f2;
img {
opacity: 1;
}
}
.isShow {
left: $base-sidebar-width;
}
.isHide {
left: 54px;
}
.next {
right: 0px;
}
.menuTabs {
line-height: 40px;
z-index: 1000;
margin: 0 28px;
display: flex;
flex-wrap: nowrap;
.page-tabs-content {
display: flex;
flex-wrap: nowrap;
}
.menuTab {
height: 40px;
display: inline-block;
cursor: pointer;
border: 1px solid rgba(222, 223, 225, 0.4);
color: #a4a4a4;
padding: 0 8px;
font-size: 14px;
white-space: nowrap;
.close {
color: #fff;
background-color: #dedfe1;
border-radius: 50%;
position: relative;
margin: 0 2px;
}
&.active .close {
color: #fff;
background-color: #bdd2f8;
}
}
}
}