'admin-21.01.22:处理tagsView及相关逻辑'

This commit is contained in:
lyt 2021-01-22 12:59:44 +08:00
parent 3f6194543e
commit a09bcf8e60
6 changed files with 70 additions and 32 deletions

View File

@ -31,6 +31,7 @@ export interface RootStateTypes {
isTagsview: boolean, isTagsview: boolean,
isBreadcrumbIcon: boolean, isBreadcrumbIcon: boolean,
isTagsviewIcon: boolean, isTagsviewIcon: boolean,
isCacheTagsView: boolean,
isFooter: boolean, isFooter: boolean,
isGrayscale: boolean, isGrayscale: boolean,
isInvert: boolean, isInvert: boolean,

View File

@ -28,6 +28,7 @@ export default {
isTagsview: true, isTagsview: true,
isBreadcrumbIcon: false, isBreadcrumbIcon: false,
isTagsviewIcon: false, isTagsviewIcon: false,
isCacheTagsView: false,
isFooter: false, isFooter: false,
isGrayscale: false, isGrayscale: false,
isInvert: false, isInvert: false,

View File

@ -182,6 +182,12 @@
<el-switch v-model="getThemeConfig.isTagsviewIcon" @change="setLocalThemeConfig"></el-switch> <el-switch v-model="getThemeConfig.isTagsviewIcon" @change="setLocalThemeConfig"></el-switch>
</div> </div>
</div> </div>
<div class="layout-breadcrumb-seting-bar-flex mt15">
<div class="layout-breadcrumb-seting-bar-flex-label">开启缓存 TagsView</div>
<div class="layout-breadcrumb-seting-bar-flex-value">
<el-switch v-model="getThemeConfig.isCacheTagsView" @change="setLocalThemeConfig"></el-switch>
</div>
</div>
<div class="layout-breadcrumb-seting-bar-flex mt15"> <div class="layout-breadcrumb-seting-bar-flex mt15">
<div class="layout-breadcrumb-seting-bar-flex-label">开启 Footer</div> <div class="layout-breadcrumb-seting-bar-flex-label">开启 Footer</div>
<div class="layout-breadcrumb-seting-bar-flex-value"> <div class="layout-breadcrumb-seting-bar-flex-value">

View File

@ -15,15 +15,12 @@ export default {
components: { BreadcrumbIndex, TagsView }, components: { BreadcrumbIndex, TagsView },
setup() { setup() {
const store = useStore(); const store = useStore();
const getThemeConfig = computed(() => { // tagsView
return store.state.themeConfig;
});
const setShowTagsView = computed(() => { const setShowTagsView = computed(() => {
let { layout } = store.state.themeConfig; let { layout } = store.state.themeConfig;
return layout !== "classic"; return layout !== "classic";
}); });
return { return {
getThemeConfig,
setShowTagsView, setShowTagsView,
}; };
}, },

View File

@ -4,10 +4,12 @@
data-popper-placement="bottom" :style="`top: ${dropdown.y + 5}px;left: ${dropdown.x}px;`" :key="Math.random()" data-popper-placement="bottom" :style="`top: ${dropdown.y + 5}px;left: ${dropdown.x}px;`" :key="Math.random()"
v-show="isShow"> v-show="isShow">
<ul class="el-dropdown-menu"> <ul class="el-dropdown-menu">
<li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" v-for="(v,k) in dropdownList" :key="k"> <template v-for="(v,k) in dropdownList" :key="k">
<i :class="v.icon"></i> <li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" v-if="!v.affix">
<span>{{v.txt}}</span> <i :class="v.icon"></i>
</li> <span>{{v.txt}}</span>
</li>
</template>
</ul> </ul>
<div class="el-popper__arrow" style="left:10px"></div> <div class="el-popper__arrow" style="left:10px"></div>
</div> </div>
@ -35,26 +37,34 @@ export default defineComponent({
isShow: false, isShow: false,
dropdownList: [ dropdownList: [
{ id: 0, txt: "刷新", affix: false, icon: "el-icon-refresh-right" }, { id: 0, txt: "刷新", affix: false, icon: "el-icon-refresh-right" },
{ id: 1, txt: "关闭", affix: true, icon: "el-icon-close" }, { id: 1, txt: "关闭", affix: false, icon: "el-icon-close" },
{ id: 2, txt: "关闭其它", affix: false, icon: "el-icon-circle-close" }, { id: 2, txt: "关闭其它", affix: false, icon: "el-icon-circle-close" },
{ id: 3, txt: "全部关闭", affix: false, icon: "el-icon-folder-delete" }, { id: 3, txt: "全部关闭", affix: false, icon: "el-icon-folder-delete" },
], ],
}); });
// x,y
const dropdown = computed(() => { const dropdown = computed(() => {
return props.dropdown; return props.dropdown;
}); });
const openContextmenu = () => { //
const openContextmenu = (meta: object) => {
meta.isAffix
? (state.dropdownList[1].affix = true)
: (state.dropdownList[1].affix = false);
closeContextmenu(); closeContextmenu();
setTimeout(() => { setTimeout(() => {
state.isShow = true; state.isShow = true;
}, 10); }, 10);
}; };
//
const closeContextmenu = () => { const closeContextmenu = () => {
state.isShow = false; state.isShow = false;
}; };
//
onMounted(() => { onMounted(() => {
document.body.addEventListener("click", closeContextmenu); document.body.addEventListener("click", closeContextmenu);
}); });
//
onUnmounted(() => { onUnmounted(() => {
document.body.removeEventListener("click", closeContextmenu); document.body.removeEventListener("click", closeContextmenu);
}); });

View File

@ -6,15 +6,15 @@
<li v-for="(v,k) in tagsViewList" :key="k" class="layout-navbars-tagsview-ul-li" <li v-for="(v,k) in tagsViewList" :key="k" class="layout-navbars-tagsview-ul-li"
:class="{'is-active':isActive(v.path)}" @contextmenu.prevent="onContextmenu(v,$event)" :class="{'is-active':isActive(v.path)}" @contextmenu.prevent="onContextmenu(v,$event)"
@click="onTagsClick(v,k)" :ref="el => { if (el) tagsRefs[k] = el }"> @click="onTagsClick(v,k)" :ref="el => { if (el) tagsRefs[k] = el }">
<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont" v-if="isActive(v.path)"></i> <i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont font14" v-if="isActive(v.path)"></i>
<i class="layout-navbars-tagsview-ul-li-iconfont" :class="v.meta.icon" <i class="layout-navbars-tagsview-ul-li-iconfont" :class="v.meta.icon"
v-if="!isActive(v.path) && getThemeConfig.isTagsviewIcon"></i> v-if="!isActive(v.path) && getThemeConfig.isTagsviewIcon"></i>
<span>{{v.meta.title}}</span> <span>{{v.meta.title}}</span>
<template v-if="isActive(v.path)"> <template v-if="isActive(v.path)">
<i class="el-icon-refresh-right ml5"></i> <i class="el-icon-refresh-right ml5"></i>
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-active"></i> <i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-active" v-if="!v.meta.isAffix"></i>
</template> </template>
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-three"></i> <i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-three" v-if="!v.meta.isAffix"></i>
</li> </li>
</ul> </ul>
</Scroll> </Scroll>
@ -31,10 +31,10 @@ import {
ref, ref,
nextTick, nextTick,
onBeforeUpdate, onBeforeUpdate,
onBeforeMount,
} from "vue"; } from "vue";
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router"; import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
import { useStore } from "/@/store/index.ts"; import { useStore } from "/@/store/index.ts";
import { setSession, getSession } from "/@/utils/storage.ts";
import Sortable from "sortablejs"; import Sortable from "sortablejs";
import Contextmenu from "/@/views/layout/navBars/tagsView/contextmenu.vue"; import Contextmenu from "/@/views/layout/navBars/tagsView/contextmenu.vue";
import Scroll from "/@/views/layout/navBars/tagsView/scroll.vue"; import Scroll from "/@/views/layout/navBars/tagsView/scroll.vue";
@ -57,6 +57,7 @@ export default {
tagsRefsIndex: 0, tagsRefsIndex: 0,
tagsViewList: [], tagsViewList: [],
}); });
// tagsView
const setTagsStyle = computed(() => { const setTagsStyle = computed(() => {
let { tagsStyle } = store.state.themeConfig; let { tagsStyle } = store.state.themeConfig;
if (tagsStyle === "tagsStyleTwo") return "layout-navbars-tagsview-ul-two"; if (tagsStyle === "tagsStyleTwo") return "layout-navbars-tagsview-ul-two";
@ -65,44 +66,63 @@ export default {
else if (tagsStyle === "tagsStyleFour") else if (tagsStyle === "tagsStyleFour")
return "layout-navbars-tagsview-ul-four"; return "layout-navbars-tagsview-ul-four";
}); });
//
const getThemeConfig = computed(() => { const getThemeConfig = computed(() => {
return store.state.themeConfig; return store.state.themeConfig;
}); });
// // // tagsViewList
const setFilterRoutes = () => { const addBrowserSetSession = () => {
console.log(store.state.tagsViewRoutes); setSession("tagsViewList", state.tagsViewList);
store.state.tagsViewRoutes.map((v) => {
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
});
}; };
// isHide tagsView // vuex isAffix
const initTagsView = () => {
if (
getSession("tagsViewList") &&
store.state.themeConfig.isCacheTagsView
) {
state.tagsViewList = getSession("tagsViewList");
} else {
store.state.tagsViewRoutes.map((v) => {
if (v.meta.isAffix && !v.meta.isHide)
state.tagsViewList.push({ ...v });
});
addTagsView(route.path);
}
//
scrollRef.value.setScrollLeft(tagsRefs);
getTagsRefsIndex(route.path);
moveToCurrentTag();
};
// tagsViewisHide tagsView
const addTagsView = (path: string) => { const addTagsView = (path: string) => {
if (state.tagsViewList.some((v) => v.path === path)) return false; if (state.tagsViewList.some((v) => v.path === path)) return false;
const item = store.state.tagsViewRoutes.find((v) => v.path === path); const item = store.state.tagsViewRoutes.find((v) => v.path === path);
if (!item.meta.isHide) state.tagsViewList.push({ ...item }); if (!item.meta.isHide) state.tagsViewList.push({ ...item });
addBrowserSetSession();
}; };
const initSortable = () => { //
const el = document.querySelector(".layout-navbars-tagsview-ul");
const sortable = Sortable.create(el, { animation: 300 });
};
const isActive = (path: string) => { const isActive = (path: string) => {
return path === state.routePath; return path === state.routePath;
}; };
// x,y props
const onContextmenu = (v: object, e: object) => { const onContextmenu = (v: object, e: object) => {
const { clientX, clientY } = e; const { clientX, clientY } = e;
state.dropdown.x = clientX; state.dropdown.x = clientX;
state.dropdown.y = clientY; state.dropdown.y = clientY;
contextmenuRef.value.openContextmenu(); contextmenuRef.value.openContextmenu(v.meta);
}; };
// tagsView
const onTagsClick = (v: object, k: number) => { const onTagsClick = (v: object, k: number) => {
state.tagsRefsIndex = k; state.tagsRefsIndex = k;
router.push(v.path); router.push(v.path);
}; };
// tagsView +
const moveToCurrentTag = () => { const moveToCurrentTag = () => {
nextTick(() => { nextTick(() => {
scrollRef.value.moveToTarget(tagsRefs.value[state.tagsRefsIndex]); scrollRef.value.moveToTarget(tagsRefs.value[state.tagsRefsIndex]);
}); });
}; };
// tagsView tagsView
const getTagsRefsIndex = (path: string) => { const getTagsRefsIndex = (path: string) => {
if (state.tagsViewList.length > 0) { if (state.tagsViewList.length > 0) {
state.tagsRefsIndex = state.tagsViewList.findIndex( state.tagsRefsIndex = state.tagsViewList.findIndex(
@ -110,16 +130,19 @@ export default {
); );
} }
}; };
// tagsView
const initSortable = () => {
const el = document.querySelector(".layout-navbars-tagsview-ul");
const sortable = Sortable.create(el, { animation: 300 });
};
//
onBeforeUpdate(() => { onBeforeUpdate(() => {
tagsRefs.value = []; tagsRefs.value = [];
}); });
onBeforeMount(() => { //
setFilterRoutes();
addTagsView(route.path);
});
onMounted(() => { onMounted(() => {
initSortable(); initSortable();
scrollRef.value.setScrollLeft(tagsRefs); initTagsView();
}); });
// //
onBeforeRouteUpdate((to) => { onBeforeRouteUpdate((to) => {
@ -180,7 +203,7 @@ export default {
&-iconfont { &-iconfont {
position: relative; position: relative;
left: -5px; left: -5px;
font-size: 14px; font-size: 12px;
} }
&-icon { &-icon {
border-radius: 100%; border-radius: 100%;