'admin-21.01.24:完成各布局导航处理、动画细节等'
This commit is contained in:
parent
a09bcf8e60
commit
94dd0f7439
@ -1,5 +1,5 @@
|
|||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"
|
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"
|
||||||
import { store } from "/@/store/index.ts";
|
import { store } from "/@/store/index.ts"
|
||||||
|
|
||||||
// 定义动态路由
|
// 定义动态路由
|
||||||
export const dynamicRoutes = [
|
export const dynamicRoutes = [
|
||||||
@ -280,7 +280,8 @@ export const dynamicRoutes = [
|
|||||||
{
|
{
|
||||||
path: '/fun',
|
path: '/fun',
|
||||||
name: 'funIndex',
|
name: 'funIndex',
|
||||||
component: () => import('/@/views/fun/index.vue'),
|
component: () => import('/@/views/layout/routerView/parent.vue'),
|
||||||
|
redirect: '/fun/tagsView',
|
||||||
meta: {
|
meta: {
|
||||||
title: '功能',
|
title: '功能',
|
||||||
isLink: '',
|
isLink: '',
|
||||||
@ -288,7 +289,22 @@ export const dynamicRoutes = [
|
|||||||
isKeepAlive: true,
|
isKeepAlive: true,
|
||||||
isAffix: false,
|
isAffix: false,
|
||||||
icon: 'iconfont icon-crew_feature'
|
icon: 'iconfont icon-crew_feature'
|
||||||
}
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/fun/tagsView',
|
||||||
|
name: 'funTagsView',
|
||||||
|
component: () => import('/@/views/fun/tagsView/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'tagsView 操作',
|
||||||
|
isLink: '',
|
||||||
|
isHide: false,
|
||||||
|
isKeepAlive: true,
|
||||||
|
isAffix: false,
|
||||||
|
icon: 'el-icon-thumb'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/pages',
|
path: '/pages',
|
||||||
|
@ -51,7 +51,6 @@ body,
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.layout-el-aside-br-color {
|
.layout-el-aside-br-color {
|
||||||
border-top: 1px solid rgb(238, 238, 238);
|
|
||||||
border-right: 1px solid rgb(238, 238, 238);
|
border-right: 1px solid rgb(238, 238, 238);
|
||||||
}
|
}
|
||||||
.layout-aside-width-default {
|
.layout-aside-width-default {
|
||||||
@ -78,6 +77,9 @@ body,
|
|||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.layout-hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* element plus 全局样式
|
/* element plus 全局样式
|
||||||
|
@ -692,6 +692,10 @@
|
|||||||
|
|
||||||
/* NavMenu 导航菜单
|
/* NavMenu 导航菜单
|
||||||
------------------------------- */
|
------------------------------- */
|
||||||
|
// 去掉默认 focus 时,背景的高亮
|
||||||
|
.el-menu-item:focus {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
// 默认样式修改
|
// 默认样式修改
|
||||||
.el-menu {
|
.el-menu {
|
||||||
border-right: none !important;
|
border-right: none !important;
|
||||||
@ -706,6 +710,7 @@
|
|||||||
// horizontal 水平方向时
|
// horizontal 水平方向时
|
||||||
.el-menu--horizontal > .el-menu-item.is-active,
|
.el-menu--horizontal > .el-menu-item.is-active,
|
||||||
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
|
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
|
||||||
|
border-bottom: 3px solid !important;
|
||||||
border-bottom-color: set-color(primary);
|
border-bottom-color: set-color(primary);
|
||||||
color: set-color(primary);
|
color: set-color(primary);
|
||||||
}
|
}
|
||||||
@ -786,6 +791,10 @@
|
|||||||
width: 24px;
|
width: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
// element plus 本身字体图标
|
||||||
|
.el-submenu [class^='el-icon-'] {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tabs 标签页
|
/* Tabs 标签页
|
||||||
------------------------------- */
|
------------------------------- */
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
funIndex
|
|
||||||
<el-input v-model="val"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { toRefs, reactive } from "vue";
|
|
||||||
export default {
|
|
||||||
name: "funIndex",
|
|
||||||
setup() {
|
|
||||||
const state = reactive({
|
|
||||||
val: "",
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
...toRefs(state),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
110
vue-admin-wonderful-next/src/views/fun/tagsView/index.vue
Normal file
110
vue-admin-wonderful-next/src/views/fun/tagsView/index.vue
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<el-card shadow="hover" header="tagsView 功能演示">
|
||||||
|
<el-form :inline="true" :model="formInline" size="small" label-width="60px" style="margin-bottom:1px;">
|
||||||
|
<el-form-item label="功能:">
|
||||||
|
<el-select v-model="formInline.selectId" placeholder="请选择">
|
||||||
|
<el-option v-for="item in selectOptions" :key="item.value" :label="item.label" :value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="路径:">
|
||||||
|
<el-input v-model="formInline.path" placeholder="路径如:/fun/tagsView" style="max-width:203px;"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="onImplementClick">点击执行</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-divider></el-divider>
|
||||||
|
<el-button type="primary" size="small" icon="el-icon-refresh-right" @click="refreshCurrentTagsView">刷新当前页
|
||||||
|
</el-button>
|
||||||
|
<el-button type="info" size="small" icon="el-icon-close" @click="closeCurrentTagsView">关闭当前页</el-button>
|
||||||
|
<el-button type="warning" size="small" icon="el-icon-circle-close" @click="closeOtherTagsView">关闭其它</el-button>
|
||||||
|
<el-button type="danger" size="small" icon="el-icon-folder-delete" @click="closeAllTagsView">全部关闭</el-button>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { getCurrentInstance, reactive, toRefs } from "vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
export default {
|
||||||
|
name: "funTagsView",
|
||||||
|
setup() {
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const route = useRoute();
|
||||||
|
const state = reactive({
|
||||||
|
formInline: {
|
||||||
|
path: "",
|
||||||
|
selectId: 0,
|
||||||
|
},
|
||||||
|
selectOptions: [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: "刷新当前",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: "关闭当前",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: "关闭其它",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
label: "关闭全部",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
// 0 刷新当前,1 关闭当前,2 关闭其它,3 关闭全部
|
||||||
|
// 1、刷新当前 tagsView
|
||||||
|
const refreshCurrentTagsView = () => {
|
||||||
|
proxy.mittBus.emit("onCurrentContextmenuClick", {
|
||||||
|
id: 0,
|
||||||
|
path: route.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 2、关闭当前 tagsView
|
||||||
|
const closeCurrentTagsView = () => {
|
||||||
|
proxy.mittBus.emit("onCurrentContextmenuClick", {
|
||||||
|
id: 1,
|
||||||
|
path: route.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 3、关闭其它 tagsView
|
||||||
|
const closeOtherTagsView = () => {
|
||||||
|
proxy.mittBus.emit("onCurrentContextmenuClick", {
|
||||||
|
id: 2,
|
||||||
|
path: route.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 4、关闭全部 tagsView
|
||||||
|
const closeAllTagsView = () => {
|
||||||
|
proxy.mittBus.emit("onCurrentContextmenuClick", {
|
||||||
|
id: 3,
|
||||||
|
path: route.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 执行点击
|
||||||
|
const onImplementClick = () => {
|
||||||
|
proxy.mittBus.emit("onCurrentContextmenuClick", {
|
||||||
|
id: state.formInline.selectId,
|
||||||
|
path: state.formInline.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
refreshCurrentTagsView,
|
||||||
|
closeCurrentTagsView,
|
||||||
|
closeOtherTagsView,
|
||||||
|
closeAllTagsView,
|
||||||
|
onImplementClick,
|
||||||
|
...toRefs(state),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -2,7 +2,7 @@
|
|||||||
<el-aside :class="setCollapseWidth">
|
<el-aside :class="setCollapseWidth">
|
||||||
<Logo v-if="setShowLogo" />
|
<Logo v-if="setShowLogo" />
|
||||||
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
|
<el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef">
|
||||||
<Vertical :menuList="menuList" />
|
<Vertical :menuList="menuList" :class="setCollapseWidth" />
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
</template>
|
</template>
|
||||||
@ -16,6 +16,7 @@ import {
|
|||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
ref,
|
ref,
|
||||||
onBeforeMount,
|
onBeforeMount,
|
||||||
|
onUnmounted,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { useStore } from "/@/store/index.ts";
|
import { useStore } from "/@/store/index.ts";
|
||||||
import { dynamicRoutes } from "/@/router/index.ts";
|
import { dynamicRoutes } from "/@/router/index.ts";
|
||||||
@ -32,6 +33,7 @@ export default {
|
|||||||
});
|
});
|
||||||
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
||||||
const setFilterRoutes = () => {
|
const setFilterRoutes = () => {
|
||||||
|
if (store.state.themeConfig.layout === "columns") return false;
|
||||||
store.dispatch("setRoutes", dynamicRoutes[0].children);
|
store.dispatch("setRoutes", dynamicRoutes[0].children);
|
||||||
state.menuList = filterRoutesFun(store.state.routes);
|
state.menuList = filterRoutesFun(store.state.routes);
|
||||||
};
|
};
|
||||||
@ -86,9 +88,26 @@ export default {
|
|||||||
proxy.$refs.layoutAsideScrollbarRef.update();
|
proxy.$refs.layoutAsideScrollbarRef.update();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 初始化
|
// 页面加载前
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
setFilterRoutes();
|
setFilterRoutes();
|
||||||
|
proxy.mittBus.on("setSendColumnsChildren", (res) => {
|
||||||
|
state.menuList = res.children;
|
||||||
|
});
|
||||||
|
proxy.mittBus.on("setSendClassicChildren", (res) => {
|
||||||
|
let { layout, isClassicSplitMenu } = store.state.themeConfig;
|
||||||
|
if (layout === "classic" && isClassicSplitMenu)
|
||||||
|
state.menuList = res.children;
|
||||||
|
});
|
||||||
|
proxy.mittBus.on("getBreadcrumbIndexSetFilterRoutes", () => {
|
||||||
|
setFilterRoutes();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 页面卸载时
|
||||||
|
onUnmounted(() => {
|
||||||
|
proxy.mittBus.off("setSendColumnsChildren");
|
||||||
|
proxy.mittBus.off("setSendClassicChildren");
|
||||||
|
proxy.mittBus.off("getBreadcrumbIndexSetFilterRoutes");
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
setCollapseWidth,
|
setCollapseWidth,
|
||||||
|
@ -2,20 +2,21 @@
|
|||||||
<div class="layout-columns-aside">
|
<div class="layout-columns-aside">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(v,k) in columnsAsideList" :key="k" @click="onColumnsAsideDown(v,k)"
|
<li v-for="(v,k) in columnsAsideList" :key="k" @click="onColumnsAsideMenuClick(v,k)"
|
||||||
:ref="el => { if (el) columnsAsideOffsetTopRefs[k] = el }" :class="{'layout-columns-active':liIndex === k} ">
|
:ref="el => { if (el) columnsAsideOffsetTopRefs[k] = el }" :class="{'layout-columns-active':liIndex === k}"
|
||||||
|
:title="v.meta.title">
|
||||||
<div class="layout-columns-aside-li-box">
|
<div class="layout-columns-aside-li-box">
|
||||||
<template v-if="!v.meta.isLink">
|
<template v-if="!v.meta.isLink">
|
||||||
<i :class="v.meta.icon"></i>
|
<i :class="v.meta.icon"></i>
|
||||||
<div class="layout-columns-aside-li-box-title">
|
<div class="layout-columns-aside-li-box-title">
|
||||||
{{v.meta.title}}
|
{{v.meta.title && v.meta.title.length >= 2 ? v.meta.title.substr(0,2) : v.meta.title}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<a :href="v.meta.isLink" target="_blank">
|
<a :href="v.meta.isLink" target="_blank">
|
||||||
<i :class="v.meta.icon"></i>
|
<i :class="v.meta.icon"></i>
|
||||||
<div class="layout-columns-aside-li-box-title">
|
<div class="layout-columns-aside-li-box-title">
|
||||||
{{v.meta.title}}
|
{{v.meta.title && v.meta.title.length >= 2 ? v.meta.title.substr(0,2) : v.meta.title}}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
@ -28,46 +29,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { reactive, toRefs, ref, computed } from "vue";
|
import {
|
||||||
|
reactive,
|
||||||
|
toRefs,
|
||||||
|
ref,
|
||||||
|
computed,
|
||||||
|
onMounted,
|
||||||
|
nextTick,
|
||||||
|
getCurrentInstance,
|
||||||
|
} from "vue";
|
||||||
|
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
|
||||||
import { useStore } from "/@/store/index.ts";
|
import { useStore } from "/@/store/index.ts";
|
||||||
|
import { dynamicRoutes } from "/@/router/index.ts";
|
||||||
export default {
|
export default {
|
||||||
name: "layoutColumnsAside",
|
name: "layoutColumnsAside",
|
||||||
setup() {
|
setup() {
|
||||||
const columnsAsideOffsetTopRefs = ref([]);
|
const columnsAsideOffsetTopRefs = ref([]);
|
||||||
const columnsAsideActiveRef = ref();
|
const columnsAsideActiveRef = ref();
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
columnsAsideList: [
|
columnsAsideList: [],
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "首页",
|
|
||||||
icon: "el-icon-medal-1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "小米",
|
|
||||||
icon: "el-icon-trophy",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "谷歌",
|
|
||||||
icon: "el-icon-basketball",
|
|
||||||
isLink: "https://www.ele.me",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "苹果",
|
|
||||||
icon: "el-icon-coffee-cup",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
liIndex: 0,
|
liIndex: 0,
|
||||||
difference: 0,
|
difference: 0,
|
||||||
});
|
});
|
||||||
@ -82,18 +66,72 @@ export default {
|
|||||||
else if (columnsAsideStyle === "columnsCard")
|
else if (columnsAsideStyle === "columnsCard")
|
||||||
return "layout-columns-card-active";
|
return "layout-columns-card-active";
|
||||||
});
|
});
|
||||||
// 设置高亮动态位置
|
// 设置菜单高亮位置移动
|
||||||
const onColumnsAsideDown = (v: Object, k: number) => {
|
const setColumnsAsideMove = (v: Object, k: number) => {
|
||||||
state.liIndex = k;
|
state.liIndex = k;
|
||||||
columnsAsideActiveRef.value.style.top = `${
|
columnsAsideActiveRef.value.style.top = `${
|
||||||
columnsAsideOffsetTopRefs.value[k].offsetTop + state.difference
|
columnsAsideOffsetTopRefs.value[k].offsetTop + state.difference
|
||||||
}px`;
|
}px`;
|
||||||
};
|
};
|
||||||
|
// 菜单高亮点击事件
|
||||||
|
const onColumnsAsideMenuClick = (v: Object, k: number) => {
|
||||||
|
setColumnsAsideMove(v, k);
|
||||||
|
let { path, redirect } = v;
|
||||||
|
if (redirect) router.push(redirect);
|
||||||
|
else router.push(path);
|
||||||
|
};
|
||||||
|
// 设置高亮动态位置
|
||||||
|
const onColumnsAsideDown = (v: Object, k: number) => {
|
||||||
|
nextTick(() => {
|
||||||
|
setColumnsAsideMove(v, k);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
||||||
|
const setFilterRoutes = () => {
|
||||||
|
store.dispatch("setRoutes", dynamicRoutes[0].children);
|
||||||
|
state.columnsAsideList = filterRoutesFun(store.state.routes);
|
||||||
|
const resData = setSendChildren(route.path);
|
||||||
|
onColumnsAsideDown(resData.item[0], resData.item[0].k);
|
||||||
|
proxy.mittBus.emit("setSendColumnsChildren", resData);
|
||||||
|
};
|
||||||
|
// 传送当前子级数据到菜单中
|
||||||
|
const setSendChildren = (path: string) => {
|
||||||
|
const currentPathSplit = path.split("/");
|
||||||
|
let currentData: object = {};
|
||||||
|
state.columnsAsideList.map((v, k) => {
|
||||||
|
if (v.path === `/${currentPathSplit[1]}`) {
|
||||||
|
v["k"] = k;
|
||||||
|
currentData["item"] = [{ ...v }];
|
||||||
|
currentData["children"] = [{ ...v }];
|
||||||
|
if (v.children) currentData["children"] = v.children;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return currentData;
|
||||||
|
};
|
||||||
|
// 路由过滤递归函数
|
||||||
|
const filterRoutesFun = (arr: Array<object>) => {
|
||||||
|
return arr
|
||||||
|
.filter((item) => !item.meta.isHide)
|
||||||
|
.map((item) => {
|
||||||
|
item = Object.assign({}, item);
|
||||||
|
if (item.children) item.children = filterRoutesFun(item.children);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 页面加载时
|
||||||
|
onMounted(() => {
|
||||||
|
setFilterRoutes();
|
||||||
|
});
|
||||||
|
// 路由更新时
|
||||||
|
onBeforeRouteUpdate((to) => {
|
||||||
|
proxy.mittBus.emit("setSendColumnsChildren", setSendChildren(to.path));
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
columnsAsideOffsetTopRefs,
|
columnsAsideOffsetTopRefs,
|
||||||
columnsAsideActiveRef,
|
columnsAsideActiveRef,
|
||||||
onColumnsAsideDown,
|
onColumnsAsideDown,
|
||||||
setColumnsAsideStyle,
|
setColumnsAsideStyle,
|
||||||
|
onColumnsAsideMenuClick,
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -118,6 +156,9 @@ export default {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
.layout-columns-aside-li-box {
|
.layout-columns-aside-li-box {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
.layout-columns-aside-li-box-title {
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -37,7 +37,7 @@ export default {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.layout-logo {
|
.layout-logo {
|
||||||
width: 220px;
|
width: 220px;
|
||||||
height: 49px;
|
height: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -20,13 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import { toRefs, reactive, computed, getCurrentInstance, onMounted } from "vue";
|
||||||
toRefs,
|
|
||||||
reactive,
|
|
||||||
onBeforeMount,
|
|
||||||
computed,
|
|
||||||
getCurrentInstance,
|
|
||||||
} from "vue";
|
|
||||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||||
import { useStore } from "/@/store/index.ts";
|
import { useStore } from "/@/store/index.ts";
|
||||||
export default {
|
export default {
|
||||||
@ -37,28 +31,55 @@ export default {
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
breadcrumbList: [{ meta: { title: "", icon: "" } }], // 定义初始值,不能为空数组,否则 v-for 报错
|
breadcrumbList: [],
|
||||||
|
routeSplit: [],
|
||||||
|
routeSplitFirst: "",
|
||||||
|
routeSplitIndex: 1,
|
||||||
});
|
});
|
||||||
const getBreadcrumbList = (matched: any) => {
|
// 获取布局配置信息
|
||||||
state.breadcrumbList = matched;
|
const getThemeConfig = computed(() => {
|
||||||
};
|
return store.state.themeConfig;
|
||||||
|
});
|
||||||
|
// 面包屑点击时
|
||||||
const onBreadcrumbClick = (v: object) => {
|
const onBreadcrumbClick = (v: object) => {
|
||||||
const { redirect, path } = v;
|
const { redirect, path } = v;
|
||||||
if (redirect) router.push(redirect);
|
if (redirect) router.push(redirect);
|
||||||
else router.push(path);
|
else router.push(path);
|
||||||
};
|
};
|
||||||
|
// 展开/收起左侧菜单点击
|
||||||
const onThemeConfigChange = () => {
|
const onThemeConfigChange = () => {
|
||||||
proxy.mittBus.emit("onMenuClick");
|
proxy.mittBus.emit("onMenuClick");
|
||||||
store.state.themeConfig.isCollapse = !store.state.themeConfig.isCollapse;
|
store.state.themeConfig.isCollapse = !store.state.themeConfig.isCollapse;
|
||||||
};
|
};
|
||||||
const getThemeConfig = computed(() => {
|
// 处理面包屑数据
|
||||||
return store.state.themeConfig;
|
const getBreadcrumbList = (arr: Array<object>) => {
|
||||||
});
|
arr.map((item) => {
|
||||||
onBeforeMount(() => {
|
state.routeSplit.map((v, k, arrs) => {
|
||||||
state.breadcrumbList = route.matched;
|
if (state.routeSplitFirst === item.path) {
|
||||||
|
state.routeSplitFirst += `/${arrs[state.routeSplitIndex]}`;
|
||||||
|
state.breadcrumbList.push(item);
|
||||||
|
state.routeSplitIndex++;
|
||||||
|
if (item.children) getBreadcrumbList(item.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 当前路由字符串切割成数组,并删除第一项空内容
|
||||||
|
const initRouteSplit = (path: string) => {
|
||||||
|
state.breadcrumbList = [store.state.routes[0]];
|
||||||
|
state.routeSplit = path.split("/");
|
||||||
|
state.routeSplit.shift();
|
||||||
|
state.routeSplitFirst = `/${state.routeSplit[0]}`;
|
||||||
|
state.routeSplitIndex = 1;
|
||||||
|
getBreadcrumbList(store.state.routes);
|
||||||
|
};
|
||||||
|
// 页面加载时
|
||||||
|
onMounted(() => {
|
||||||
|
initRouteSplit(route.path);
|
||||||
});
|
});
|
||||||
|
// 路由更新时
|
||||||
onBeforeRouteUpdate((to) => {
|
onBeforeRouteUpdate((to) => {
|
||||||
getBreadcrumbList(to.matched);
|
initRouteSplit(to.path);
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
onThemeConfigChange,
|
onThemeConfigChange,
|
||||||
|
@ -8,8 +8,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, reactive, toRefs } from "vue";
|
import {
|
||||||
|
computed,
|
||||||
|
reactive,
|
||||||
|
toRefs,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
getCurrentInstance,
|
||||||
|
} from "vue";
|
||||||
|
import { useRoute, onBeforeRouteUpdate } from "vue-router";
|
||||||
import { useStore } from "/@/store/index.ts";
|
import { useStore } from "/@/store/index.ts";
|
||||||
|
import { dynamicRoutes } from "/@/router/index.ts";
|
||||||
import Breadcrumb from "/@/views/layout/navBars/breadcrumb/breadcrumb.vue";
|
import Breadcrumb from "/@/views/layout/navBars/breadcrumb/breadcrumb.vue";
|
||||||
import User from "/@/views/layout/navBars/breadcrumb/user.vue";
|
import User from "/@/views/layout/navBars/breadcrumb/user.vue";
|
||||||
import Logo from "/@/views/layout/logo/index.vue";
|
import Logo from "/@/views/layout/logo/index.vue";
|
||||||
@ -18,59 +27,17 @@ export default {
|
|||||||
name: "layoutBreadcrumbIndex",
|
name: "layoutBreadcrumbIndex",
|
||||||
components: { Breadcrumb, User, Logo, Horizontal },
|
components: { Breadcrumb, User, Logo, Horizontal },
|
||||||
setup() {
|
setup() {
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
const route = useRoute();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
menuList: [
|
menuList: [],
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "首页",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
meta: {
|
|
||||||
title: "微软",
|
|
||||||
icon: "el-icon-s-flag",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/docs",
|
|
||||||
meta: {
|
|
||||||
title: "文档",
|
|
||||||
icon: "el-icon-s-flag",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/docs1",
|
|
||||||
meta: {
|
|
||||||
title: "文档1",
|
|
||||||
icon: "el-icon-s-flag",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/docs2",
|
|
||||||
meta: {
|
|
||||||
title: "文档2",
|
|
||||||
icon: "el-icon-s-management",
|
|
||||||
isLink: "https://www.ele.me",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/docs3",
|
|
||||||
meta: {
|
|
||||||
title: "文档3",
|
|
||||||
icon: "el-icon-s-management",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
// 获取布局配置信息
|
||||||
const getThemeConfig = computed(() => {
|
const getThemeConfig = computed(() => {
|
||||||
return store.state.themeConfig;
|
return store.state.themeConfig;
|
||||||
});
|
});
|
||||||
|
// 设置 logo 显示/隐藏
|
||||||
const setIsShowLogo = computed(() => {
|
const setIsShowLogo = computed(() => {
|
||||||
let { isShowLogo, layout } = store.state.themeConfig;
|
let { isShowLogo, layout } = store.state.themeConfig;
|
||||||
return (
|
return (
|
||||||
@ -78,12 +45,76 @@ export default {
|
|||||||
(isShowLogo && layout === "transverse")
|
(isShowLogo && layout === "transverse")
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
// 设置是否显示横向导航菜单
|
||||||
const isLayoutTransverse = computed(() => {
|
const isLayoutTransverse = computed(() => {
|
||||||
let { layout, isClassicSplitMenu } = store.state.themeConfig;
|
let { layout, isClassicSplitMenu } = store.state.themeConfig;
|
||||||
return (
|
return (
|
||||||
layout === "transverse" || (isClassicSplitMenu && layout === "classic")
|
layout === "transverse" || (isClassicSplitMenu && layout === "classic")
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
||||||
|
const setFilterRoutes = () => {
|
||||||
|
let { layout, isClassicSplitMenu } = store.state.themeConfig;
|
||||||
|
store.dispatch("setRoutes", dynamicRoutes[0].children);
|
||||||
|
if (layout === "classic" && isClassicSplitMenu) {
|
||||||
|
state.menuList = delClassicChildren(
|
||||||
|
filterRoutesFun(store.state.routes)
|
||||||
|
);
|
||||||
|
const resData = setSendClassicChildren(route.path);
|
||||||
|
proxy.mittBus.emit("setSendClassicChildren", resData);
|
||||||
|
} else {
|
||||||
|
state.menuList = filterRoutesFun(store.state.routes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 设置了分割菜单时,删除底下 children
|
||||||
|
const delClassicChildren = (arr: Array<object>) => {
|
||||||
|
arr.map((v) => {
|
||||||
|
if (v.children) delete v.children;
|
||||||
|
});
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
|
// 路由过滤递归函数
|
||||||
|
const filterRoutesFun = (arr: Array<object>) => {
|
||||||
|
return arr
|
||||||
|
.filter((item) => !item.meta.isHide)
|
||||||
|
.map((item) => {
|
||||||
|
item = Object.assign({}, item);
|
||||||
|
if (item.children) item.children = filterRoutesFun(item.children);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 传送当前子级数据到菜单中
|
||||||
|
const setSendClassicChildren = (path: string) => {
|
||||||
|
const currentPathSplit = path.split("/");
|
||||||
|
let currentData: object = {};
|
||||||
|
filterRoutesFun(store.state.routes).map((v, k) => {
|
||||||
|
if (v.path === `/${currentPathSplit[1]}`) {
|
||||||
|
v["k"] = k;
|
||||||
|
currentData["item"] = [{ ...v }];
|
||||||
|
currentData["children"] = [{ ...v }];
|
||||||
|
if (v.children) currentData["children"] = v.children;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return currentData;
|
||||||
|
};
|
||||||
|
// 页面加载时
|
||||||
|
onMounted(() => {
|
||||||
|
setFilterRoutes();
|
||||||
|
proxy.mittBus.on("getBreadcrumbIndexSetFilterRoutes", () => {
|
||||||
|
setFilterRoutes();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 页面卸载时
|
||||||
|
onUnmounted(() => {
|
||||||
|
proxy.mittBus.off("getBreadcrumbIndexSetFilterRoutes");
|
||||||
|
});
|
||||||
|
// 路由更新时
|
||||||
|
onBeforeRouteUpdate((to) => {
|
||||||
|
proxy.mittBus.emit(
|
||||||
|
"setSendClassicChildren",
|
||||||
|
setSendClassicChildren(to.path)
|
||||||
|
);
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
getThemeConfig,
|
getThemeConfig,
|
||||||
setIsShowLogo,
|
setIsShowLogo,
|
||||||
@ -102,5 +133,6 @@ export default {
|
|||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
background: var(--bg-topBar);
|
background: var(--bg-topBar);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border-bottom: 1px solid rgb(238, 238, 238);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -40,6 +40,8 @@
|
|||||||
</el-color-picker>
|
</el-color-picker>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 菜单 / 顶栏 -->
|
||||||
<el-divider content-position="left">菜单 / 顶栏</el-divider>
|
<el-divider content-position="left">菜单 / 顶栏</el-divider>
|
||||||
<div class="layout-breadcrumb-seting-bar-flex">
|
<div class="layout-breadcrumb-seting-bar-flex">
|
||||||
<div class="layout-breadcrumb-seting-bar-flex-label">顶栏背景</div>
|
<div class="layout-breadcrumb-seting-bar-flex-label">顶栏背景</div>
|
||||||
@ -158,10 +160,12 @@
|
|||||||
<el-switch v-model="getThemeConfig.isShowLogo" @change="onIsShowLogoChange"></el-switch>
|
<el-switch v-model="getThemeConfig.isShowLogo" @change="onIsShowLogoChange"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout-breadcrumb-seting-bar-flex mt15">
|
<div class="layout-breadcrumb-seting-bar-flex mt15"
|
||||||
|
:style="{opacity:getThemeConfig.layout === 'transverse' ? 0.5 : 1}">
|
||||||
<div class="layout-breadcrumb-seting-bar-flex-label">面包屑 Breadcrumb</div>
|
<div class="layout-breadcrumb-seting-bar-flex-label">面包屑 Breadcrumb</div>
|
||||||
<div class="layout-breadcrumb-seting-bar-flex-value">
|
<div class="layout-breadcrumb-seting-bar-flex-value">
|
||||||
<el-switch v-model="getThemeConfig.isBreadcrumb" @change="onIsBreadcrumbChange"></el-switch>
|
<el-switch v-model="getThemeConfig.isBreadcrumb" :disabled="getThemeConfig.layout === 'transverse'"
|
||||||
|
@change="onIsBreadcrumbChange"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout-breadcrumb-seting-bar-flex mt15">
|
<div class="layout-breadcrumb-seting-bar-flex mt15">
|
||||||
@ -183,7 +187,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">开启缓存 TagsView</div>
|
<div class="layout-breadcrumb-seting-bar-flex-label">开启 TagsView 缓存 </div>
|
||||||
<div class="layout-breadcrumb-seting-bar-flex-value">
|
<div class="layout-breadcrumb-seting-bar-flex-value">
|
||||||
<el-switch v-model="getThemeConfig.isCacheTagsView" @change="setLocalThemeConfig"></el-switch>
|
<el-switch v-model="getThemeConfig.isCacheTagsView" @change="setLocalThemeConfig"></el-switch>
|
||||||
</div>
|
</div>
|
||||||
@ -432,6 +436,7 @@ export default defineComponent({
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let els = document.querySelector(".el-menu-item.is-active");
|
let els = document.querySelector(".el-menu-item.is-active");
|
||||||
|
if (!els) return false;
|
||||||
let attr = "el-menu-item is-active";
|
let attr = "el-menu-item is-active";
|
||||||
if (getThemeConfig.value.isMenuBarColorHighlight)
|
if (getThemeConfig.value.isMenuBarColorHighlight)
|
||||||
els.setAttribute("class", `${attr} add-is-active`);
|
els.setAttribute("class", `${attr} add-is-active`);
|
||||||
@ -458,6 +463,7 @@ export default defineComponent({
|
|||||||
const onClassicSplitMenuChange = () => {
|
const onClassicSplitMenuChange = () => {
|
||||||
getThemeConfig.value.isBreadcrumb = false;
|
getThemeConfig.value.isBreadcrumb = false;
|
||||||
setLocalThemeConfig();
|
setLocalThemeConfig();
|
||||||
|
proxy.mittBus.emit("getBreadcrumbIndexSetFilterRoutes");
|
||||||
};
|
};
|
||||||
// 4、界面显示 --> 侧边栏 Logo
|
// 4、界面显示 --> 侧边栏 Logo
|
||||||
const onIsShowLogoChange = () => {
|
const onIsShowLogoChange = () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-navbars-breadcrumb-user">
|
<div class="layout-navbars-breadcrumb-user" :style="setFlexAutoStyle">
|
||||||
<div class="layout-navbars-breadcrumb-user-icon">
|
<div class="layout-navbars-breadcrumb-user-icon">
|
||||||
<i class="el-icon-search" title="菜单搜索"></i>
|
<i class="el-icon-search" title="菜单搜索"></i>
|
||||||
</div>
|
</div>
|
||||||
@ -29,16 +29,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, getCurrentInstance } from "vue";
|
import { ref, getCurrentInstance, computed } from "vue";
|
||||||
|
import { useStore } from "/@/store/index.ts";
|
||||||
export default {
|
export default {
|
||||||
name: "layoutBreadcrumbUser",
|
name: "layoutBreadcrumbUser",
|
||||||
setup() {
|
setup() {
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const store = useStore();
|
||||||
const onLayoutSetingClick = () => {
|
const onLayoutSetingClick = () => {
|
||||||
proxy.mittBus.emit("openSetingsDrawer");
|
proxy.mittBus.emit("openSetingsDrawer");
|
||||||
};
|
};
|
||||||
|
const setFlexAutoStyle = computed(() => {
|
||||||
|
if (
|
||||||
|
!store.state.themeConfig.isBreadcrumb &&
|
||||||
|
store.state.themeConfig.layout !== "transverse" &&
|
||||||
|
!store.state.themeConfig.isClassicSplitMenu
|
||||||
|
)
|
||||||
|
return { flex: 1 };
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
onLayoutSetingClick,
|
onLayoutSetingClick,
|
||||||
|
setFlexAutoStyle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -48,7 +59,6 @@ export default {
|
|||||||
.layout-navbars-breadcrumb-user {
|
.layout-navbars-breadcrumb-user {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex: 1;
|
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
&-link {
|
&-link {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
v-show="isShow">
|
v-show="isShow">
|
||||||
<ul class="el-dropdown-menu">
|
<ul class="el-dropdown-menu">
|
||||||
<template v-for="(v,k) in dropdownList" :key="k">
|
<template v-for="(v,k) in dropdownList" :key="k">
|
||||||
<li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" v-if="!v.affix">
|
<li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" v-if="!v.affix"
|
||||||
|
@click="onCurrentContextmenuClick(v.id)">
|
||||||
<i :class="v.icon"></i>
|
<i :class="v.icon"></i>
|
||||||
<span>{{v.txt}}</span>
|
<span>{{v.txt}}</span>
|
||||||
</li>
|
</li>
|
||||||
@ -32,7 +33,7 @@ export default defineComponent({
|
|||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props, { emit }) {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
isShow: false,
|
isShow: false,
|
||||||
dropdownList: [
|
dropdownList: [
|
||||||
@ -41,14 +42,20 @@ export default defineComponent({
|
|||||||
{ 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" },
|
||||||
],
|
],
|
||||||
|
path: {},
|
||||||
});
|
});
|
||||||
// 父级传过来的坐标 x,y 值
|
// 父级传过来的坐标 x,y 值
|
||||||
const dropdown = computed(() => {
|
const dropdown = computed(() => {
|
||||||
return props.dropdown;
|
return props.dropdown;
|
||||||
});
|
});
|
||||||
|
// 当前项菜单点击
|
||||||
|
const onCurrentContextmenuClick = (id: number) => {
|
||||||
|
emit("currentContextmenuClick", { id, path: state.path });
|
||||||
|
};
|
||||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
||||||
const openContextmenu = (meta: object) => {
|
const openContextmenu = (item: object) => {
|
||||||
meta.isAffix
|
state.path = item.path;
|
||||||
|
item.meta.isAffix
|
||||||
? (state.dropdownList[1].affix = true)
|
? (state.dropdownList[1].affix = true)
|
||||||
: (state.dropdownList[1].affix = false);
|
: (state.dropdownList[1].affix = false);
|
||||||
closeContextmenu();
|
closeContextmenu();
|
||||||
@ -72,6 +79,7 @@ export default defineComponent({
|
|||||||
dropdown,
|
dropdown,
|
||||||
openContextmenu,
|
openContextmenu,
|
||||||
closeContextmenu,
|
closeContextmenu,
|
||||||
|
onCurrentContextmenuClick,
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -59,10 +59,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const updateScrollbar = () => {
|
||||||
|
proxy.$refs.elScrollbarRef.update();
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
setScrollLeft,
|
setScrollLeft,
|
||||||
onHandleScroll,
|
onHandleScroll,
|
||||||
moveToTarget,
|
moveToTarget,
|
||||||
|
updateScrollbar,
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
v-show="getThemeConfig.isTagsview">
|
v-show="getThemeConfig.isTagsview">
|
||||||
<Scroll ref="scrollRef">
|
<Scroll ref="scrollRef">
|
||||||
<ul class="layout-navbars-tagsview-ul" :class="setTagsStyle">
|
<ul class="layout-navbars-tagsview-ul" :class="setTagsStyle">
|
||||||
<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" :data-name="v.name"
|
||||||
: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 font14" v-if="isActive(v.path)"></i>
|
<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont font14" v-if="isActive(v.path)"></i>
|
||||||
@ -11,15 +11,17 @@
|
|||||||
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" @click="refreshCurrentTagsView(v.path)"></i>
|
||||||
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-active" v-if="!v.meta.isAffix"></i>
|
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-active" v-if="!v.meta.isAffix"
|
||||||
|
@click="closeCurrentTagsView(v.path)"></i>
|
||||||
</template>
|
</template>
|
||||||
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-three" v-if="!v.meta.isAffix"></i>
|
<i class="el-icon-close layout-navbars-tagsview-ul-li-icon layout-icon-three" v-if="!v.meta.isAffix"
|
||||||
|
@click="closeCurrentTagsView(v.path)"></i>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
<Contextmenu :dropdown="dropdown" ref="contextmenuRef" />
|
<Contextmenu :dropdown="dropdown" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -31,6 +33,9 @@ import {
|
|||||||
ref,
|
ref,
|
||||||
nextTick,
|
nextTick,
|
||||||
onBeforeUpdate,
|
onBeforeUpdate,
|
||||||
|
onBeforeMount,
|
||||||
|
onUnmounted,
|
||||||
|
getCurrentInstance,
|
||||||
} 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";
|
||||||
@ -42,6 +47,7 @@ export default {
|
|||||||
name: "layoutTagsView",
|
name: "layoutTagsView",
|
||||||
components: { Contextmenu, Scroll },
|
components: { Contextmenu, Scroll },
|
||||||
setup() {
|
setup() {
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const tagsRefs = ref([]);
|
const tagsRefs = ref([]);
|
||||||
const scrollRef = ref();
|
const scrollRef = ref();
|
||||||
const contextmenuRef = ref();
|
const contextmenuRef = ref();
|
||||||
@ -71,8 +77,8 @@ export default {
|
|||||||
return store.state.themeConfig;
|
return store.state.themeConfig;
|
||||||
});
|
});
|
||||||
// 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录
|
// 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录
|
||||||
const addBrowserSetSession = () => {
|
const addBrowserSetSession = (tagsViewList: Array<object>) => {
|
||||||
setSession("tagsViewList", state.tagsViewList);
|
setSession("tagsViewList", tagsViewList);
|
||||||
};
|
};
|
||||||
// vuex 中获取路由信息:如果是设置了固定的(isAffix),进行初始化显示
|
// vuex 中获取路由信息:如果是设置了固定的(isAffix),进行初始化显示
|
||||||
const initTagsView = () => {
|
const initTagsView = () => {
|
||||||
@ -93,12 +99,71 @@ export default {
|
|||||||
getTagsRefsIndex(route.path);
|
getTagsRefsIndex(route.path);
|
||||||
moveToCurrentTag();
|
moveToCurrentTag();
|
||||||
};
|
};
|
||||||
// 添加 tagsView:未设置隐藏(isHide)也添加到在 tagsView 中
|
// 1、添加 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();
|
addBrowserSetSession(state.tagsViewList);
|
||||||
|
};
|
||||||
|
// 2、刷新当前 tagsView:
|
||||||
|
const refreshCurrentTagsView = (path: string) => {
|
||||||
|
proxy.mittBus.emit("onTagsViewRefreshRouterView", path);
|
||||||
|
};
|
||||||
|
// 3、关闭当前 tagsView:如果是设置了固定的(isAffix),不可以关闭
|
||||||
|
const closeCurrentTagsView = (path: string) => {
|
||||||
|
state.tagsViewList.map((v, k, arr) => {
|
||||||
|
if (!v.meta.isAffix) {
|
||||||
|
if (v.path === path) {
|
||||||
|
state.tagsViewList.splice(k, 1);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push(arr[arr.length - 1].path);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addBrowserSetSession(state.tagsViewList);
|
||||||
|
};
|
||||||
|
// 4、关闭其它 tagsView:如果是设置了固定的(isAffix),不进行关闭
|
||||||
|
const closeOtherTagsView = (path: string) => {
|
||||||
|
state.tagsViewList = [];
|
||||||
|
store.state.tagsViewRoutes.map((v) => {
|
||||||
|
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
|
||||||
|
});
|
||||||
|
addTagsView(path);
|
||||||
|
};
|
||||||
|
// 5、关闭全部 tagsView:如果是设置了固定的(isAffix),不进行关闭
|
||||||
|
const closeAllTagsView = (path: string) => {
|
||||||
|
state.tagsViewList = [];
|
||||||
|
store.state.tagsViewRoutes.map((v) => {
|
||||||
|
if (v.meta.isAffix && !v.meta.isHide) {
|
||||||
|
state.tagsViewList.push({ ...v });
|
||||||
|
if (state.tagsViewList.some((v) => v.path === path))
|
||||||
|
router.push(path);
|
||||||
|
else router.push(v.path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addBrowserSetSession(state.tagsViewList);
|
||||||
|
};
|
||||||
|
// 当前项右键菜单点击
|
||||||
|
const onCurrentContextmenuClick = (data: object) => {
|
||||||
|
let { id, path } = data;
|
||||||
|
switch (id) {
|
||||||
|
case 0:
|
||||||
|
refreshCurrentTagsView(path);
|
||||||
|
router.push(path);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
closeCurrentTagsView(path);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
router.push(path);
|
||||||
|
closeOtherTagsView(path);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
closeAllTagsView(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// 判断页面高亮
|
// 判断页面高亮
|
||||||
const isActive = (path: string) => {
|
const isActive = (path: string) => {
|
||||||
@ -109,7 +174,7 @@ export default {
|
|||||||
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(v.meta);
|
contextmenuRef.value.openContextmenu(v);
|
||||||
};
|
};
|
||||||
// 当前的 tagsView 项点击时
|
// 当前的 tagsView 项点击时
|
||||||
const onTagsClick = (v: object, k: number) => {
|
const onTagsClick = (v: object, k: number) => {
|
||||||
@ -120,21 +185,49 @@ export default {
|
|||||||
const moveToCurrentTag = () => {
|
const moveToCurrentTag = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
scrollRef.value.moveToTarget(tagsRefs.value[state.tagsRefsIndex]);
|
scrollRef.value.moveToTarget(tagsRefs.value[state.tagsRefsIndex]);
|
||||||
|
scrollRef.value.updateScrollbar();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 获取 tagsView 的下标:用于处理 tagsView 点击时的横向滚动
|
// 获取 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(
|
const tagsRefsFindIndex = state.tagsViewList.findIndex(
|
||||||
(item) => item.path === path
|
(item) => item.path === path
|
||||||
);
|
);
|
||||||
|
if (tagsRefsFindIndex <= 0) return false;
|
||||||
|
state.tagsRefsIndex = tagsRefsFindIndex;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 设置 tagsView 可以进行拖拽
|
// 设置 tagsView 可以进行拖拽
|
||||||
const initSortable = () => {
|
const initSortable = () => {
|
||||||
const el = document.querySelector(".layout-navbars-tagsview-ul");
|
const el = document.querySelector(".layout-navbars-tagsview-ul");
|
||||||
const sortable = Sortable.create(el, { animation: 300 });
|
if (!el) return false;
|
||||||
|
const sortable = Sortable.create(el, {
|
||||||
|
animation: 300,
|
||||||
|
dataIdAttr: "data-name",
|
||||||
|
onEnd: () => {
|
||||||
|
const sortEndList = [];
|
||||||
|
sortable.toArray().map((val) => {
|
||||||
|
state.tagsViewList.map((v) => {
|
||||||
|
if (v.name === val) sortEndList.push({ ...v });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
addBrowserSetSession(sortEndList);
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
// 数据加载前
|
||||||
|
onBeforeMount(() => {
|
||||||
|
// 监听非本页面调用 0 刷新当前,1 关闭当前,2 关闭其它,3 关闭全部
|
||||||
|
proxy.mittBus.on("onCurrentContextmenuClick", (data: object) => {
|
||||||
|
onCurrentContextmenuClick(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 页面卸载时
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 取消非本页面调用监听
|
||||||
|
proxy.mittBus.off("onCurrentContextmenuClick");
|
||||||
|
});
|
||||||
// 数据更新时
|
// 数据更新时
|
||||||
onBeforeUpdate(() => {
|
onBeforeUpdate(() => {
|
||||||
tagsRefs.value = [];
|
tagsRefs.value = [];
|
||||||
@ -160,6 +253,9 @@ export default {
|
|||||||
scrollRef,
|
scrollRef,
|
||||||
getThemeConfig,
|
getThemeConfig,
|
||||||
setTagsStyle,
|
setTagsStyle,
|
||||||
|
refreshCurrentTagsView,
|
||||||
|
closeCurrentTagsView,
|
||||||
|
onCurrentContextmenuClick,
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -170,7 +266,6 @@ export default {
|
|||||||
.layout-navbars-tagsview {
|
.layout-navbars-tagsview {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-top: 1px solid rgb(238, 238, 238);
|
|
||||||
&-ul {
|
&-ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-menu router :default-active="defaultActive" background-color="transparent" mode="horizontal">
|
<div class="el-menu-horizontal-warp">
|
||||||
<template v-for="val in menuList">
|
<el-scrollbar @wheel.native.prevent="onElMenuHorizontalScroll" ref="elMenuHorizontalScrollRef">
|
||||||
<el-submenu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
|
<el-menu router :default-active="defaultActive" background-color="transparent" mode="horizontal">
|
||||||
<template #title>
|
<template v-for="val in menuList">
|
||||||
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
|
<el-submenu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
|
||||||
<span>{{ val.meta.title }}</span>
|
<template #title>
|
||||||
|
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
|
||||||
|
<span>{{ val.meta.title }}</span>
|
||||||
|
</template>
|
||||||
|
<SubItem :chil="val.children" />
|
||||||
|
</el-submenu>
|
||||||
|
<el-menu-item :index="val.path" :key="val.path" v-else>
|
||||||
|
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
|
||||||
|
<template #title v-if="!val.meta.isLink">{{ val.meta.title }}</template>
|
||||||
|
<template #title v-else><a :href="val.meta.isLink" target="_blank">{{ val.meta.title }}</a></template>
|
||||||
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
<SubItem :chil="val.children" />
|
</el-menu>
|
||||||
</el-submenu>
|
</el-scrollbar>
|
||||||
<el-menu-item :index="val.path" :key="val.path" v-else>
|
</div>
|
||||||
<i :class="val.meta.icon ? val.meta.icon : ''"></i>
|
|
||||||
<template #title v-if="!val.meta.isLink">{{ val.meta.title }}</template>
|
|
||||||
<template #title v-else><a :href="val.meta.isLink" target="_blank">{{ val.meta.title }}</a></template>
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
</el-menu>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -24,8 +28,11 @@ import {
|
|||||||
computed,
|
computed,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
|
onMounted,
|
||||||
|
nextTick,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { useRoute, onBeforeRouteUpdate } from "vue-router";
|
import { useRoute, onBeforeRouteUpdate } from "vue-router";
|
||||||
|
import { useStore } from "/@/store/index.ts";
|
||||||
import SubItem from "/@/views/layout/navMenu/subItem.vue";
|
import SubItem from "/@/views/layout/navMenu/subItem.vue";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "navMenuHorizontal",
|
name: "navMenuHorizontal",
|
||||||
@ -41,20 +48,67 @@ export default defineComponent({
|
|||||||
setup(props) {
|
setup(props) {
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const store = useStore();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
defaultActive: route.path,
|
defaultActive: null,
|
||||||
});
|
});
|
||||||
|
// 获取父级菜单数据
|
||||||
const menuList = computed(() => {
|
const menuList = computed(() => {
|
||||||
return props.menuList;
|
return props.menuList;
|
||||||
});
|
});
|
||||||
|
// 设置横向滚动条可以鼠标滚轮滚动
|
||||||
|
const onElMenuHorizontalScroll = (e: object) => {
|
||||||
|
const eventDelta = e.wheelDelta || -e.deltaY * 40;
|
||||||
|
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft =
|
||||||
|
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft +
|
||||||
|
eventDelta / 4;
|
||||||
|
};
|
||||||
|
// 初始化数据,页面刷新时,滚动条滚动到对应位置
|
||||||
|
const initElMenuOffsetLeft = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
let els = document.querySelector(
|
||||||
|
".el-menu.el-menu--horizontal li.is-active"
|
||||||
|
);
|
||||||
|
if (!els) return false;
|
||||||
|
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft =
|
||||||
|
els.offsetLeft;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 设置页面当前路由高亮
|
||||||
|
const setCurrentRouterHighlight = (path: string) => {
|
||||||
|
const currentPathSplit = path.split("/");
|
||||||
|
if (store.state.themeConfig.layout === "classic") {
|
||||||
|
state.defaultActive = `/${currentPathSplit[1]}`;
|
||||||
|
} else {
|
||||||
|
state.defaultActive = path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 页面加载时
|
||||||
|
onMounted(() => {
|
||||||
|
initElMenuOffsetLeft();
|
||||||
|
setCurrentRouterHighlight(route.path);
|
||||||
|
});
|
||||||
|
// 路由更新时
|
||||||
onBeforeRouteUpdate((to) => {
|
onBeforeRouteUpdate((to) => {
|
||||||
state.defaultActive = to.path;
|
setCurrentRouterHighlight(to.path);
|
||||||
proxy.mittBus.emit("onMenuClick");
|
proxy.mittBus.emit("onMenuClick");
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
menuList,
|
menuList,
|
||||||
|
onElMenuHorizontalScroll,
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.el-menu-horizontal-warp {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-right: 30px;
|
||||||
|
.el-menu.el-menu--horizontal {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from "vue";
|
import { computed, defineComponent } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "navMenuSubItem",
|
name: "navMenuSubItem",
|
||||||
props: {
|
props: {
|
||||||
@ -31,7 +30,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const route = useRoute();
|
// 获取父级菜单数据
|
||||||
const chil = computed(() => {
|
const chil = computed(() => {
|
||||||
return props.chil;
|
return props.chil;
|
||||||
});
|
});
|
||||||
|
@ -49,12 +49,15 @@ export default defineComponent({
|
|||||||
const state = reactive({
|
const state = reactive({
|
||||||
defaultActive: route.path,
|
defaultActive: route.path,
|
||||||
});
|
});
|
||||||
|
// 获取父级菜单数据
|
||||||
const menuList = computed(() => {
|
const menuList = computed(() => {
|
||||||
return props.menuList;
|
return props.menuList;
|
||||||
});
|
});
|
||||||
|
// 获取布局配置信息
|
||||||
const getThemeConfig = computed(() => {
|
const getThemeConfig = computed(() => {
|
||||||
return store.state.themeConfig;
|
return store.state.themeConfig;
|
||||||
});
|
});
|
||||||
|
// 路由更新时
|
||||||
onBeforeRouteUpdate((to) => {
|
onBeforeRouteUpdate((to) => {
|
||||||
state.defaultActive = to.path;
|
state.defaultActive = to.path;
|
||||||
proxy.mittBus.emit("onMenuClick");
|
proxy.mittBus.emit("onMenuClick");
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="h100">
|
||||||
<router-view v-slot="{ Component, route }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition :name="setTransitionName" mode="out-in">
|
<transition :name="setTransitionName" mode="out-in">
|
||||||
<keep-alive :include="getCaches">
|
<keep-alive :include="getCaches">
|
||||||
<component :is="Component" :key="route.path" />
|
<component :is="Component" :key="refreshRouterViewKey" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
@ -18,18 +18,28 @@ import {
|
|||||||
reactive,
|
reactive,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
watch,
|
watch,
|
||||||
|
onBeforeMount,
|
||||||
|
onUnmounted,
|
||||||
|
nextTick,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { useRouter, RouteRecordRaw } from "vue-router";
|
import {
|
||||||
|
useRoute,
|
||||||
|
useRouter,
|
||||||
|
RouteRecordRaw,
|
||||||
|
onBeforeRouteUpdate,
|
||||||
|
} from "vue-router";
|
||||||
import { useStore } from "/@/store/index.ts";
|
import { useStore } from "/@/store/index.ts";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "layoutParentView",
|
name: "layoutParentView",
|
||||||
setup() {
|
setup() {
|
||||||
const router = useRouter();
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
transitionName: "slide-right",
|
transitionName: "slide-right",
|
||||||
headerHeight: "84px",
|
headerHeight: "84px",
|
||||||
|
refreshRouterViewKey: route.path,
|
||||||
});
|
});
|
||||||
// 设置主界面切换动画
|
// 设置主界面切换动画
|
||||||
const setTransitionName = computed(() => {
|
const setTransitionName = computed(() => {
|
||||||
@ -57,6 +67,24 @@ export default defineComponent({
|
|||||||
proxy.$refs.layoutScrollbarRef.update();
|
proxy.$refs.layoutScrollbarRef.update();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 路由更新时
|
||||||
|
onBeforeRouteUpdate((to) => {
|
||||||
|
state.refreshRouterViewKey = to.path;
|
||||||
|
});
|
||||||
|
// 页面加载时
|
||||||
|
onBeforeMount(() => {
|
||||||
|
proxy.mittBus.on("onTagsViewRefreshRouterView", (path: string) => {
|
||||||
|
if (route.path !== path) return false;
|
||||||
|
state.refreshRouterViewKey = Math.random();
|
||||||
|
nextTick(() => {
|
||||||
|
state.refreshRouterViewKey = path;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 页面卸载时
|
||||||
|
onUnmounted(() => {
|
||||||
|
proxy.mittBus.off("onTagsViewRefreshRouterView");
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
getThemeConfig,
|
getThemeConfig,
|
||||||
getCaches,
|
getCaches,
|
||||||
|
@ -6,13 +6,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toRefs, reactive } from "vue";
|
import { toRefs, reactive, onActivated, onMounted } from "vue";
|
||||||
export default {
|
export default {
|
||||||
name: "menu13",
|
name: "menu13",
|
||||||
setup() {
|
setup() {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
val: "",
|
val: "",
|
||||||
});
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
console.log(2222);
|
||||||
|
});
|
||||||
|
onActivated(() => {
|
||||||
|
console.log(1111);
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user