mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 13:43:51 +08:00
'admin-21.01.22:处理tagsView及相关逻辑'
This commit is contained in:
parent
3f6194543e
commit
a09bcf8e60
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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">
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
|
};
|
||||||
|
// 添加 tagsView:未设置隐藏(isHide)也添加到在 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%;
|
||||||
|
Loading…
Reference in New Issue
Block a user