<template>
|
<div>
|
<!-- 右侧用户登录图标 -->
|
<div class="user-logininfo">
|
<div class="logoIcon" v-if="logo">
|
<div class="image">
|
<img src="../../assets/logo.jpg" alt="" srcset="" />
|
</div>
|
</div>
|
<div class="user-logininfo-icon" v-else>
|
<!-- 折叠 -->
|
<i @click="clickFold" class="el-icon-s-fold"></i>
|
<!-- 标签列表 -->
|
<div class="tag-list-container" @wheel.prevent="handleWheel">
|
<div class="tag-list" v-for="tag in tagList" :key="tag.name">
|
<div
|
@click="goTag(tag)"
|
:class="{ activeTag: tag.path === $route.path }"
|
>
|
{{ tag.meta.title }}
|
</div>
|
<i
|
@click="closeTag(tag)"
|
v-if="tagList.length > 1"
|
class="el-icon-close"
|
></i>
|
</div>
|
</div>
|
</div>
|
<div class="user-info">
|
<img src="@/assets/public/photo.png" />
|
<div class="user-info-text">欢迎您,{{ userInfo.nickName }}</div>
|
<div class="user-info-line"></div>
|
<div @click="outLogin" class="user-info-out">
|
<img src="@/assets/public/logOut.png" />
|
<div class="user-info-out-text">退出登录</div>
|
</div>
|
</div>
|
</div>
|
<el-dialog
|
top="40vh"
|
:visible.sync="show"
|
:show-close="false"
|
:append-to-body="true"
|
:close-on-click-modal="false"
|
width="433px"
|
>
|
<div class="top-con a-center" slot="title">
|
<div class="left">
|
<img
|
src="@/assets/public/notice@2x.png"
|
style="width: 24px; height: 24px; margin-right: 14px"
|
/>
|
<div class="title">{{ "提示" }}</div>
|
</div>
|
</div>
|
<div class="lh--32 fs--20">
|
{{ "当前页面可能有未保存数据,确认关闭么" }}
|
</div>
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="show = false">取消</el-button>
|
<el-button type='danger' @click="submitClose">{{ "确认" }}</el-button>
|
</span>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import { mapState } from "vuex";
|
export default {
|
data() {
|
return {
|
userInfo: "",
|
scrollTimer: null,
|
scrollAmount: 0,
|
show: false,
|
pendingCloseTag: null,
|
};
|
},
|
props: {
|
logo: {
|
type: String,
|
default: "",
|
},
|
},
|
computed: {
|
...mapState(["tagList", "isFold"]),
|
},
|
mounted() {
|
// 获取用户信息
|
this.getUserInfo();
|
},
|
methods: {
|
// 点击折叠按钮
|
clickFold() {
|
this.$store.commit("SET_ISFOLD", !this.isFold);
|
},
|
// 获取用户信息
|
getUserInfo() {
|
this.userInfo = JSON.parse(sessionStorage.getItem("userInfo"));
|
},
|
// 退出登录
|
outLogin() {
|
sessionStorage.clear();
|
this.$router.replace({ path: "/" });
|
},
|
// 关闭标签
|
closeTag(tag) {
|
if (tag.path && tag.path.includes('add')) {
|
this.pendingCloseTag = tag;
|
this.show = true;
|
return;
|
}
|
this._doCloseTag(tag);
|
},
|
// 真正执行关闭标签的逻辑
|
_doCloseTag(tag) {
|
this.$store.commit(
|
"SET_TAGLIST",
|
this.tagList.filter((item) => item.path !== tag.path)
|
);
|
// 判断是否是当前标签
|
if (tag.path === this.$route.path) {
|
this.$router.push(this.tagList[this.tagList.length - 1].path);
|
}
|
},
|
submitClose() {
|
this.show = false;
|
if (this.pendingCloseTag) {
|
this._doCloseTag(this.pendingCloseTag);
|
this.pendingCloseTag = null;
|
}
|
},
|
// 跳转标签
|
goTag(tag) {
|
this.$router.push({
|
path: tag.path,
|
query: tag.query,
|
});
|
},
|
handleWheel(e) {
|
if (this.scrollTimer) {
|
this.scrollAmount += e.deltaY;
|
return;
|
}
|
|
const container = e.currentTarget;
|
this.scrollAmount = e.deltaY;
|
|
const scroll = () => {
|
container.scrollLeft += this.scrollAmount * 1.2; // 增加滚动速度
|
this.scrollAmount = 0;
|
this.scrollTimer = null;
|
};
|
|
this.scrollTimer = setTimeout(scroll, 8); // 减少延迟时间
|
},
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
// 右侧用户头像
|
.user-logininfo {
|
height: 100%;
|
padding-left: 32px;
|
padding-right: 20px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
overflow: hidden;
|
|
.image {
|
// margin-top: 40px;
|
width: 70px;
|
height: 70px;
|
|
img {
|
width: 100%;
|
height: 100%;
|
border-radius: 50%;
|
}
|
}
|
|
.user-logininfo-icon {
|
margin-right: 30px;
|
flex: 1;
|
display: flex;
|
align-items: center;
|
min-width: 0;
|
overflow: hidden;
|
|
i:first-child {
|
margin-right: 21px;
|
}
|
|
i {
|
cursor: pointer;
|
}
|
|
.tag-list-container {
|
display: flex;
|
align-items: center;
|
overflow-x: auto;
|
flex: 1;
|
min-width: 0;
|
scroll-behavior: auto; // 移除平滑滚动,提高性能
|
-webkit-overflow-scrolling: touch;
|
|
.tag-list {
|
flex-shrink: 0;
|
display: flex;
|
align-items: center;
|
cursor: pointer;
|
font-weight: 400;
|
font-size: 18px;
|
color: rgba(0, 0, 0, 0.6);
|
margin-right: 40px;
|
|
div:hover {
|
font-weight: bold;
|
color: #049c9a;
|
}
|
|
i {
|
margin-left: 10px;
|
|
&:hover {
|
color: #049c9a;
|
}
|
}
|
}
|
|
.activeTag {
|
font-weight: bold;
|
color: #049c9a;
|
}
|
}
|
}
|
|
.user-info {
|
flex-shrink: 0;
|
display: flex;
|
align-items: center;
|
|
img {
|
width: 26px;
|
height: 26px;
|
border-radius: 50%;
|
}
|
|
.user-info-text {
|
margin-left: 16px;
|
font-size: 14px;
|
color: #303133;
|
font-weight: 400;
|
}
|
|
.user-info-line {
|
width: 1px;
|
height: 12px;
|
background-color: #979797;
|
margin: 0 20px;
|
}
|
|
.user-info-out {
|
display: flex;
|
align-items: center;
|
padding: 0 11px;
|
border-radius: 12px;
|
position: relative;
|
background: transparent;
|
cursor: pointer;
|
|
&::before {
|
content: "";
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
border-radius: 12px;
|
padding: 1px;
|
background: linear-gradient(
|
180deg,
|
rgba(10, 203, 202, 1),
|
rgba(4, 156, 154, 1)
|
);
|
-webkit-mask: linear-gradient(#fff 0 0) content-box,
|
linear-gradient(#fff 0 0);
|
-webkit-mask-composite: xor;
|
mask-composite: exclude;
|
}
|
|
.user-info-out-text {
|
font-weight: 400;
|
font-size: 14px;
|
color: #049c9a;
|
line-height: 21px;
|
position: relative;
|
z-index: 1;
|
}
|
|
img {
|
width: 14px;
|
height: 14px;
|
margin-right: 7px;
|
position: relative;
|
z-index: 1;
|
}
|
}
|
}
|
}
|
.left {
|
display: flex;
|
}
|
|
::v-deep .el-dialog {
|
border-radius: 12px;
|
|
.el-dialog__header {
|
padding-top: 28px;
|
padding-right: 27px;
|
padding-left: 34px;
|
padding-bottom: 11px;
|
}
|
|
.el-dialog__body {
|
padding: unset;
|
padding-left: 73px;
|
padding-right: 20px;
|
}
|
|
.el-dialog__footer {
|
padding-top: 18px;
|
padding-right: 27px;
|
padding-bottom: 29px;
|
}
|
}
|
|
.bgcolor1 {
|
background: rgba(22, 119, 255, 1);
|
}
|
|
.top-con {
|
display: flex;
|
justify-content: space-between;
|
|
.title {
|
font-family: PingFangSC, PingFang SC;
|
font-weight: 600;
|
font-size: 16px;
|
color: rgba(0, 0, 0, 1);
|
margin-bottom: 13px;
|
}
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: end;
|
gap: 10px;
|
}
|
</style>
|