|
@@ -0,0 +1,228 @@
|
|
|
+<template>
|
|
|
+ <el-card class="box-card">
|
|
|
+ <div class="tags" ref="tags" :style="{ padding: '6px 10px' }">
|
|
|
+ <div class="tags-out-box" ref="outBox">
|
|
|
+ <div
|
|
|
+ class="tags-box"
|
|
|
+ ref="box"
|
|
|
+ :style="{
|
|
|
+ 'padding-left': '0',
|
|
|
+ left: `${left}px`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-tag
|
|
|
+ ref="tag"
|
|
|
+ size="small"
|
|
|
+ v-for="(tag, i) in tags"
|
|
|
+ :data-index="i"
|
|
|
+ :data-id="tag.name"
|
|
|
+ :key="tag.name"
|
|
|
+ :closable="tag.name !== 'home' && tag.name !== '驾驶舱'"
|
|
|
+ :effect="$route.name === tag.name ? 'dark' : 'plain'"
|
|
|
+ class="tagBox"
|
|
|
+ :class="{
|
|
|
+ 'selected-tag':
|
|
|
+ $route.name === tag.name || $route.name === 'cockpitManage',
|
|
|
+ 'unselected-tag': $route.name !== tag.name,
|
|
|
+ }"
|
|
|
+ @contextmenu.native.prevent="handleClickContextMenu($event, tag, i)"
|
|
|
+ @click="handleTagClick($event, tag)"
|
|
|
+ @close="handleTagClose(tag, i)"
|
|
|
+ >
|
|
|
+ {{ tag.label }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <ul
|
|
|
+ class="right-menu"
|
|
|
+ :style="{ left: menuLeft, top: menuTop, zIndex: 99 }"
|
|
|
+ v-show="contextMenuVisible"
|
|
|
+ >
|
|
|
+ <a href="javascript:;" @click="refresh">刷新</a>
|
|
|
+ <a href="javascript:;" @click="closeAllTag">关闭所有</a>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapState, mapActions } from "vuex";
|
|
|
+
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ contextMenuVisible: false, // 是否显示菜单
|
|
|
+ menuLeft: "", // 右键菜单距离浏览器左边的距离
|
|
|
+ menuTop: "", // 右键菜单距离浏览器上边的距离
|
|
|
+ tagIndex: 0, // 当前点击的tag的索引
|
|
|
+ tag: {}, // 当前右键点击的tag对象
|
|
|
+ arrowVisible: false, // 是否显示箭头
|
|
|
+ tagsBoxWidth: 0, // ref 为 outBox 的长度
|
|
|
+ tagsWidth: 0, // ref 为 tags 的长度
|
|
|
+ left: 0, // ref 为 box 节点相对于左边的距离,用于箭头点击
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState({
|
|
|
+ tags: (state) => state.menuTag.tagList,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...mapActions("menuTag", [
|
|
|
+ "addTag",
|
|
|
+ "removeTag",
|
|
|
+ "removeOtherTags",
|
|
|
+ "removeAllTags",
|
|
|
+ "setTagList",
|
|
|
+ ]),
|
|
|
+ handleClickContextMenu(event, tag, index) {
|
|
|
+ this.contextMenuVisible = true;
|
|
|
+ this.menuLeft = `${event.clientX}px`;
|
|
|
+ this.menuTop = `${event.clientY}px`;
|
|
|
+ this.tagIndex = index;
|
|
|
+ this.tag = tag;
|
|
|
+ },
|
|
|
+ handleTagClick(event, tag) {
|
|
|
+ this.contextMenuVisible = false;
|
|
|
+ // 点击标签时的处理逻辑
|
|
|
+ // 例如:导航到标签对应的页面
|
|
|
+ this.$router.push(tag.path);
|
|
|
+ },
|
|
|
+ handleTagClose(tag, index) {
|
|
|
+ // 关闭标签时的处理逻辑
|
|
|
+ if (tag.name !== "home") {
|
|
|
+ this.removeTag(tag);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ refresh() {
|
|
|
+ // 刷新标签页的逻辑
|
|
|
+ this.$router.push({ path: this.tag.path, query: { refresh: true } });
|
|
|
+ this.contextMenuVisible = false;
|
|
|
+ },
|
|
|
+ closeAllTag() {
|
|
|
+ // 关闭所有标签的逻辑
|
|
|
+ this.removeAllTags();
|
|
|
+ this.contextMenuVisible = false;
|
|
|
+ },
|
|
|
+ updateArrowVisibility() {
|
|
|
+ this.tagsBoxWidth = this.$refs.outBox.offsetWidth;
|
|
|
+ this.tagsWidth = this.$refs.box.scrollWidth;
|
|
|
+ console.log();
|
|
|
+ // this.arrowVisible = this.tagsWidth > this.tagsBoxWidth;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ tags() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.updateArrowVisibility();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.updateArrowVisibility();
|
|
|
+ window.addEventListener("resize", this.updateArrowVisibility);
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ window.removeEventListener("resize", this.updateArrowVisibility);
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+::v-deep.box-card {
|
|
|
+ border: 0 !important;
|
|
|
+ border-bottom: 1px solid #d8dce5 !important;
|
|
|
+ -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12),
|
|
|
+ 0 0 3px 0 rgba(0, 0, 0, 0.04) !important;
|
|
|
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04) !important;
|
|
|
+ .tags-out-box {
|
|
|
+ width: 100%;
|
|
|
+ .tags-box {
|
|
|
+ width: 100%;
|
|
|
+ overflow-x: scroll;
|
|
|
+ }
|
|
|
+ .tags-box::-webkit-scrollbar {
|
|
|
+ width: 0px;
|
|
|
+ height: 0px;
|
|
|
+ background: transparent; /* 隐藏滚动条 */
|
|
|
+ }
|
|
|
+ .tags-box {
|
|
|
+ scrollbar-width: none; /* 隐藏滚动条 */
|
|
|
+ -ms-overflow-style: none; /* 隐藏滚动条(旧版 Internet Explorer 和 Edge) */
|
|
|
+ }
|
|
|
+
|
|
|
+ .tags-box::-webkit-scrollbar {
|
|
|
+ width: 0px;
|
|
|
+ height: 0px;
|
|
|
+ background: transparent; /* 隐藏滚动条 */
|
|
|
+ }
|
|
|
+ .tags-box {
|
|
|
+ overflow: -moz-scrollbars-none; /* 隐藏滚动条(旧版 Firefox) */
|
|
|
+ -ms-overflow-style: none; /* 隐藏滚动条(旧版 Internet Explorer 和 Edge) */
|
|
|
+ scrollbar-width: none; /* 隐藏滚动条(Firefox) */
|
|
|
+ }
|
|
|
+
|
|
|
+ .tags-box::-webkit-scrollbar {
|
|
|
+ width: 0px;
|
|
|
+ height: 0px;
|
|
|
+ background: transparent; /* 隐藏滚动条(Webkit 浏览器) */
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+::v-deep.box-card .el-card__body {
|
|
|
+ padding: 0 !important;
|
|
|
+}
|
|
|
+.tagBox {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.tags {
|
|
|
+ width: 100%;
|
|
|
+ white-space: nowrap;
|
|
|
+ background-color: #fff;
|
|
|
+ // padding: 12px 10px;
|
|
|
+
|
|
|
+ &-out-box {
|
|
|
+ display: inline-block;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-box {
|
|
|
+ position: relative;
|
|
|
+ transition: 0.3s;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.el-tag {
|
|
|
+ margin: 0 5px;
|
|
|
+
|
|
|
+ // &.selected-tag {
|
|
|
+ // background-color: #409eff !important; // 选中的背景色
|
|
|
+ // color: #fff; // 选中的文字颜色
|
|
|
+ // }
|
|
|
+
|
|
|
+ &.unselected-tag {
|
|
|
+ background-color: #fff !important; // 未选中的背景色
|
|
|
+ color: #333 !important; // 未选中的文字颜色
|
|
|
+ border-color: #ccc !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.right-menu {
|
|
|
+ position: absolute;
|
|
|
+ background-color: #fff;
|
|
|
+ border: 1px solid #dcdcdc;
|
|
|
+ list-style: none;
|
|
|
+ padding: 10px 0;
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
|
+
|
|
|
+ a {
|
|
|
+ display: block;
|
|
|
+ padding: 5px 20px;
|
|
|
+ color: #666;
|
|
|
+ text-decoration: none;
|
|
|
+ &:hover {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|