feat: add tagViews right click menu

This commit is contained in:
xiaoxian521 2021-04-24 17:19:41 +08:00
parent 69d2f82835
commit a0074411ca

View File

@ -1,15 +1,31 @@
<template> <template>
<div class="tags-view" v-if="!showTags"> <div ref="containerDom" class="tags-view" v-if="!showTags">
<el-scrollbar :vertical="false" class="scroll-container"> <el-scrollbar :vertical="false" class="scroll-container">
<div <div
v-for="(item, index) in dynamicTagList" v-for="(item, index) in dynamicTagList"
:key="index" :key="index"
:class="['scroll-item', $route.path === item.path ? 'active' : '']" :class="['scroll-item', $route.path === item.path ? 'active' : '']"
@contextmenu.prevent.native="openMenu(item, $event)"
> >
<router-link :to="item.path">{{ $t(item.meta.title) }}</router-link> <router-link :to="item.path">{{ $t(item.meta.title) }}</router-link>
<span v-if="index !== 0 " class="el-icon-close" @click="deleteMenu(item)"></span> <span v-if="index !== 0 " class="el-icon-close" @click="deleteMenu(item)"></span>
</div> </div>
</el-scrollbar> </el-scrollbar>
<!-- 右键菜单按钮 -->
<ul
v-show="visible"
:style="{ left: buttonLeft + 'px',top: buttonTop + 'px'}"
class="contextmenu"
>
<div v-for="(item,key) in tagsViews" :key="key" style="display:flex; align-items: center;">
<li v-if="item.show" @click="selectTag(item,key)">
<span>
<i :class="item.icon"></i>
</span>
{{item.text}}
</li>
</div>
</ul>
<!-- 右侧功能按钮 --> <!-- 右侧功能按钮 -->
<ul class="right-func"> <ul class="right-func">
<li> <li>
@ -43,135 +59,211 @@
</div> </div>
</template> </template>
<script> <script lang='ts'>
import { useDynamicRoutesHook } from "./tagsHook" import { useDynamicRoutesHook } from "./tagsHook";
import { useRoute, useRouter } from "vue-router" import { useRoute, useRouter } from "vue-router";
import { ref, watchEffect, onBeforeMount, unref, nextTick } from "vue" import { ref, watchEffect, watch, onBeforeMount, unref, nextTick } from "vue";
import { storageLocal } from "/@/utils/storage" import { storageLocal } from "/@/utils/storage";
import { emitter } from "/@/utils/mitt" import { emitter } from "/@/utils/mitt";
import { toggleClass, removeClass } from "/@/utils/operate" import { toggleClass, removeClass } from "/@/utils/operate";
import { homeRoute } from "./type" import { templateRef } from "@vueuse/core";
let refreshDiv = "refresh-div" import { homeRoute } from "./type";
let refreshDiv = "refresh-div";
export default { export default {
setup() { setup() {
const { deleteDynamicTag, dynamicRouteTags, dRoutes, routesLength } = useDynamicRoutesHook() const {
const route = useRoute() deleteDynamicTag,
const router = useRouter() dynamicRouteTags,
const showTags = ref(storageLocal.getItem("tagsVal") || false) dRoutes,
routesLength
} = useDynamicRoutesHook();
const route = useRoute();
const router = useRouter();
const showTags = ref(storageLocal.getItem("tagsVal") || false);
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
const tagsViews = ref([ const tagsViews = ref([
{ {
icon: "el-icon-refresh-right", icon: "el-icon-refresh-right",
text: "重新加载", text: "重新加载",
divided: false, divided: false,
disabled: false disabled: false,
show: true
}, },
{ {
icon: "el-icon-close", icon: "el-icon-close",
text: "关闭当前标签页", text: "关闭当前标签页",
divided: false, divided: false,
disabled: unref(routesLength) > 1 ? false : true disabled: unref(routesLength) > 1 ? false : true,
show: true
}, },
{ {
icon: "el-icon-more", icon: "el-icon-more",
text: "关闭其他标签页", text: "关闭其他标签页",
divided: true, divided: true,
disabled: unref(routesLength) > 2 ? false : true disabled: unref(routesLength) > 2 ? false : true,
show: true
}, },
{ {
icon: "el-icon-minus", icon: "el-icon-minus",
text: "关闭全部标签页", text: "关闭全部标签页",
divided: false, divided: false,
disabled: unref(routesLength) > 1 ? false : true disabled: unref(routesLength) > 1 ? false : true,
}, show: true
]) }
]);
let visible = ref(false);
let buttonLeft = ref(0);
let buttonTop = ref(0);
//
let currentSelect = ref({});
function deleteMenu(item) { function deleteMenu(item) {
let tagslen = storageLocal.getItem("routesInStorage").length let tagslen = storageLocal.getItem("routesInStorage").length;
if (tagslen === 2) { if (tagslen === 2) {
Array.from([1, 2, 3]).forEach(v => { Array.from([1, 2, 3]).forEach(v => {
tagsViews.value[v].disabled = true tagsViews.value[v].disabled = true;
}) });
} }
if (tagslen === 3) { if (tagslen === 3) {
tagsViews.value[2].disabled = true tagsViews.value[2].disabled = true;
} }
deleteDynamicTag(item, route.path) deleteDynamicTag(item, route.path);
} }
// tabview // tabview
let stop = watchEffect(() => { let stop = watchEffect(() => {
let parentPath = route.path.slice(0, route.path.lastIndexOf("/")) let parentPath = route.path.slice(0, route.path.lastIndexOf("/"));
dynamicRouteTags(route.path, parentPath) dynamicRouteTags(route.path, parentPath);
}) });
setTimeout(() => { setTimeout(() => {
// //
stop() stop();
}) });
function onFresh() { function onFresh() {
toggleClass(true, refreshDiv, document.querySelector(".rotate")) toggleClass(true, refreshDiv, document.querySelector(".rotate"));
const { path, fullPath } = unref(route) const { path, fullPath } = unref(route);
router.replace({ router.replace({
path: "/redirect" + fullPath path: "/redirect" + fullPath
}) });
setTimeout(() => { setTimeout(() => {
removeClass(document.querySelector(".rotate"), refreshDiv) removeClass(document.querySelector(".rotate"), refreshDiv);
}, 600) }, 600);
} }
function onClickDrop(key, item) { function onClickDrop(key, item, selectRoute) {
if (item.disabled) return if (item && item.disabled) return;
// //
switch (key) { switch (key) {
case 0: case 0:
// //
onFresh() onFresh();
break break;
case 1: case 1:
// //
deleteMenu({ path: route.path, meta: route.meta }) selectRoute
break ? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
: deleteMenu({ path: route.path, meta: route.meta });
break;
case 2: case 2:
// //
dRoutes.value = [homeRoute, { path: route.path, meta: route.meta }] dRoutes.value = selectRoute
storageLocal.setItem("routesInStorage", dRoutes.value) ? [homeRoute, { path: selectRoute.path, meta: selectRoute.meta }]
tagsViews.value[2].disabled = true : [homeRoute, { path: route.path, meta: route.meta }];
break storageLocal.setItem("routesInStorage", dRoutes.value);
tagsViews.value[2].disabled = true;
if (selectRoute) router.push(selectRoute.path);
break;
case 3: case 3:
// //
dRoutes.value = [homeRoute] dRoutes.value = [homeRoute];
storageLocal.setItem("routesInStorage", dRoutes.value) storageLocal.setItem("routesInStorage", dRoutes.value);
router.push("/welcome") router.push("/welcome");
Array.from([1, 2, 3]).forEach(v => { Array.from([1, 2, 3]).forEach(v => {
tagsViews.value[v].disabled = true tagsViews.value[v].disabled = true;
}) });
break break;
} }
} }
onBeforeMount(() => { function selectTag(item, key) {
emitter.on("tagViewsChange", (key) => { onClickDrop(key, {}, currentSelect.value);
if (unref(showTags) === key) return }
showTags.value = key
})
emitter.on("changLayoutRoute", (indexPath) => { function openMenu(tag, e) {
let currentLen = storageLocal.getItem("routesInStorage").length if (tag.path === "/welcome") {
//
Array.from([1, 2, 3]).forEach(v => {
tagsViews.value[v].show = false;
});
tagsViews.value[0].show = true;
} else if (route.path !== tag.path) {
//
tagsViews.value[0].show = false;
Array.from([1, 2, 3]).forEach(v => {
tagsViews.value[v].show = true;
});
} else {
Array.from([0, 1, 2, 3]).forEach(v => {
tagsViews.value[v].show = true;
});
}
currentSelect.value = tag;
const menuMinWidth = 105;
const offsetLeft = unref(containerDom).getBoundingClientRect().left;
const offsetWidth = unref(containerDom).offsetWidth;
const maxLeft = offsetWidth - menuMinWidth;
const left = e.clientX - offsetLeft + 15;
if (left > maxLeft) {
buttonLeft.value = maxLeft;
} else {
buttonLeft.value = left;
}
buttonTop.value = e.offsetY * 2;
visible.value = true;
}
function closeMenu() {
visible.value = false;
}
watch(
() => visible.value,
val => {
if (val) {
document.body.addEventListener("click", closeMenu);
} else {
document.body.removeEventListener("click", closeMenu);
}
}
);
onBeforeMount(() => {
emitter.on("tagViewsChange", key => {
if (unref(showTags) === key) return;
showTags.value = key;
});
emitter.on("changLayoutRoute", indexPath => {
let currentLen = storageLocal.getItem("routesInStorage").length;
if (currentLen === 1) { if (currentLen === 1) {
Array.from([1, 3]).forEach(v => { Array.from([1, 3]).forEach(v => {
tagsViews.value[v].disabled = false tagsViews.value[v].disabled = false;
}) });
} }
if (currentLen >= 2) { if (currentLen >= 2) {
Array.from([1, 2, 3]).forEach(v => { Array.from([1, 2, 3]).forEach(v => {
tagsViews.value[v].disabled = false tagsViews.value[v].disabled = false;
}) });
} }
}) });
}) });
return { return {
dynamicTagList: dRoutes, dynamicTagList: dRoutes,
@ -179,9 +271,16 @@ export default {
showTags, showTags,
onFresh, onFresh,
tagsViews, tagsViews,
onClickDrop onClickDrop,
} visible,
}, buttonLeft,
buttonTop,
openMenu,
closeMenu,
selectTag,
currentSelect
};
}
}; };
</script> </script>
@ -220,6 +319,28 @@ export default {
} }
} }
} }
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
} }
.el-icon-close { .el-icon-close {