初始化项目
This commit is contained in:
95
src/view/layout/aside/asideComponent/asyncSubmenu.vue
Normal file
95
src/view/layout/aside/asideComponent/asyncSubmenu.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<el-sub-menu ref="subMenu" :index="routerInfo.name">
|
||||
|
||||
<template #title>
|
||||
<div v-if="!isCollapse" class="gva-subMenu">
|
||||
<el-icon v-if="routerInfo.meta.icon">
|
||||
<component :is="routerInfo.meta.icon" />
|
||||
</el-icon>
|
||||
<span>{{ routerInfo.meta.title }}</span>
|
||||
</div>
|
||||
<template v-else>
|
||||
<el-icon v-if="routerInfo.meta.icon">
|
||||
<component :is="routerInfo.meta.icon" />
|
||||
</el-icon>
|
||||
<span>{{ routerInfo.meta.title }}</span>
|
||||
</template>
|
||||
</template>
|
||||
<slot />
|
||||
</el-sub-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AsyncSubmenu',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
const props = defineProps({
|
||||
routerInfo: {
|
||||
default: function() {
|
||||
return null
|
||||
},
|
||||
type: Object
|
||||
},
|
||||
isCollapse: {
|
||||
default: function() {
|
||||
return false
|
||||
},
|
||||
type: Boolean
|
||||
},
|
||||
theme: {
|
||||
default: function() {
|
||||
return {}
|
||||
},
|
||||
type: Object
|
||||
}
|
||||
})
|
||||
|
||||
const activeBackground = ref(props.theme.activeBackground)
|
||||
const activeText = ref(props.theme.activeText)
|
||||
const normalText = ref(props.theme.normalText)
|
||||
// const hoverBackground = ref(props.theme.hoverBackground)
|
||||
// const hoverText = ref(props.theme.hoverText)
|
||||
|
||||
watch(() => props.theme, () => {
|
||||
activeBackground.value = props.theme.activeBackground
|
||||
activeText.value = props.theme.activeText
|
||||
normalText.value = props.theme.normalText
|
||||
// hoverBackground.value = props.theme.hoverBackground
|
||||
// hoverText.value = props.theme.hoverText
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-sub-menu{
|
||||
::v-deep(.el-sub-menu__title){
|
||||
padding: 6px;
|
||||
color: v-bind(normalText);
|
||||
}
|
||||
}
|
||||
|
||||
.is-active:not(.is-opened){
|
||||
::v-deep(.el-sub-menu__title) .gva-subMenu{
|
||||
flex:1;
|
||||
height: 100%;
|
||||
line-height: 44px;
|
||||
background: v-bind(activeBackground) !important;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 2px 1px v-bind(activeBackground) !important;
|
||||
i{
|
||||
color: v-bind(activeText);
|
||||
}
|
||||
span{
|
||||
color: v-bind(activeText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gva-subMenu {
|
||||
padding-left: 4px;
|
||||
}
|
||||
</style>
|
59
src/view/layout/aside/asideComponent/index.vue
Normal file
59
src/view/layout/aside/asideComponent/index.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<component
|
||||
:is="menuComponent"
|
||||
v-if="!routerInfo.hidden"
|
||||
:is-collapse="isCollapse"
|
||||
:theme="theme"
|
||||
:router-info="routerInfo"
|
||||
>
|
||||
<template v-if="routerInfo.children&&routerInfo.children.length">
|
||||
<AsideComponent
|
||||
v-for="item in routerInfo.children"
|
||||
:key="item.name"
|
||||
:is-collapse="false"
|
||||
:router-info="item"
|
||||
:theme="theme"
|
||||
/>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AsideComponent',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import MenuItem from './menuItem.vue'
|
||||
import AsyncSubmenu from './asyncSubmenu.vue'
|
||||
import { computed } from 'vue'
|
||||
const props = defineProps({
|
||||
routerInfo: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
isCollapse: {
|
||||
default: function() {
|
||||
return false
|
||||
},
|
||||
type: Boolean
|
||||
},
|
||||
theme: {
|
||||
default: function() {
|
||||
return {}
|
||||
},
|
||||
type: Object
|
||||
}
|
||||
})
|
||||
|
||||
const menuComponent = computed(() => {
|
||||
if (props.routerInfo.children && props.routerInfo.children.filter(item => !item.hidden).length) {
|
||||
return AsyncSubmenu
|
||||
} else {
|
||||
return MenuItem
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
121
src/view/layout/aside/asideComponent/menuItem.vue
Normal file
121
src/view/layout/aside/asideComponent/menuItem.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<el-menu-item :index="routerInfo.name">
|
||||
<template v-if="isCollapse">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="light"
|
||||
:content="routerInfo.meta.title"
|
||||
placement="right"
|
||||
>
|
||||
<el-icon v-if="routerInfo.meta.icon">
|
||||
<component :is="routerInfo.meta.icon" />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="gva-menu-item">
|
||||
<el-icon v-if="routerInfo.meta.icon">
|
||||
<component :is="routerInfo.meta.icon" />
|
||||
</el-icon>
|
||||
<span class="gva-menu-item-title">{{ routerInfo.meta.title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MenuItem',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
routerInfo: {
|
||||
default: function() {
|
||||
return null
|
||||
},
|
||||
type: Object
|
||||
},
|
||||
isCollapse: {
|
||||
default: function() {
|
||||
return false
|
||||
},
|
||||
type: Boolean
|
||||
},
|
||||
theme: {
|
||||
default: function() {
|
||||
return {}
|
||||
},
|
||||
type: Object
|
||||
}
|
||||
})
|
||||
|
||||
const activeBackground = ref(props.theme.activeBackground)
|
||||
const activeText = ref(props.theme.activeText)
|
||||
const normalText = ref(props.theme.normalText)
|
||||
const hoverBackground = ref(props.theme.hoverBackground)
|
||||
const hoverText = ref(props.theme.hoverText)
|
||||
|
||||
watch(() => props.theme, () => {
|
||||
activeBackground.value = props.theme.activeBackground
|
||||
activeText.value = props.theme.activeText
|
||||
normalText.value = props.theme.normalText
|
||||
hoverBackground.value = props.theme.hoverBackground
|
||||
hoverText.value = props.theme.hoverText
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.gva-menu-item{
|
||||
width: 100%;
|
||||
flex:1;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-left: 4px;
|
||||
|
||||
.gva-menu-item-title {
|
||||
flex:1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu--collapse{
|
||||
.el-menu-item.is-active{
|
||||
color: v-bind(activeBackground);
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu-item{
|
||||
color: v-bind(normalText);
|
||||
}
|
||||
|
||||
.el-menu-item.is-active{
|
||||
.gva-menu-item{
|
||||
background: v-bind(activeBackground) !important;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 2px 1px v-bind(activeBackground) !important;
|
||||
i{
|
||||
color: v-bind(activeText);
|
||||
}
|
||||
span{
|
||||
color: v-bind(activeText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu-item:hover{
|
||||
.gva-menu-item{
|
||||
background: v-bind(hoverBackground);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 2px 1px v-bind(hoverBackground);
|
||||
color: v-bind(hoverText);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
363
src/view/layout/aside/historyComponent/history.vue
Normal file
363
src/view/layout/aside/historyComponent/history.vue
Normal file
@@ -0,0 +1,363 @@
|
||||
<template>
|
||||
<div class="router-history">
|
||||
<el-tabs
|
||||
v-model="activeValue"
|
||||
:closable="!(historys.length === 1 && $route.name === defaultRouter)"
|
||||
type="card"
|
||||
@contextmenu.prevent="openContextMenu($event)"
|
||||
@tab-click="changeTab"
|
||||
@tab-remove="removeTab"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="item in historys"
|
||||
:key="name(item)"
|
||||
:label="item.meta.title"
|
||||
:name="name(item)"
|
||||
:tab="item"
|
||||
class="gva-tab"
|
||||
>
|
||||
<template #label>
|
||||
<span
|
||||
:tab="item"
|
||||
:style="{
|
||||
color: activeValue === name(item) ? userStore.activeColor : '#333',
|
||||
}"
|
||||
><i
|
||||
class="dot"
|
||||
:style="{
|
||||
backgroundColor:
|
||||
activeValue === name(item) ? userStore.activeColor : '#ddd',
|
||||
}"
|
||||
/>
|
||||
{{ fmtTitle(item.meta.title,item) }}</span>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!--自定义右键菜单html代码-->
|
||||
<ul
|
||||
v-show="contextMenuVisible"
|
||||
:style="{ left: left + 'px', top: top + 'px' }"
|
||||
class="contextmenu"
|
||||
>
|
||||
<li @click="closeAll">关闭所有</li>
|
||||
<li @click="closeLeft">关闭左侧</li>
|
||||
<li @click="closeRight">关闭右侧</li>
|
||||
<li @click="closeOther">关闭其他</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HistoryComponent',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { emitter } from '@/utils/bus.js'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/pinia/modules/user'
|
||||
import { fmtTitle } from '@/utils/fmtRouterTitle'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const getFmtString = (item) => {
|
||||
return item.name + JSON.stringify(item.query) + JSON.stringify(item.params)
|
||||
}
|
||||
|
||||
const historys = ref([])
|
||||
const activeValue = ref('')
|
||||
const contextMenuVisible = ref(false)
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const name = (item) => {
|
||||
return (
|
||||
item.name + JSON.stringify(item.query) + JSON.stringify(item.params)
|
||||
)
|
||||
}
|
||||
|
||||
const left = ref(0)
|
||||
const top = ref(0)
|
||||
const isCollapse = ref(false)
|
||||
const isMobile = ref(false)
|
||||
const rightActive = ref('')
|
||||
const defaultRouter = computed(() => userStore.userInfo.authority.defaultRouter)
|
||||
const openContextMenu = (e) => {
|
||||
if (
|
||||
historys.value.length === 1 &&
|
||||
route.name === defaultRouter.value
|
||||
) {
|
||||
return false
|
||||
}
|
||||
let id = ''
|
||||
if (e.srcElement.nodeName === 'SPAN') {
|
||||
id = e.srcElement.offsetParent.id
|
||||
} else {
|
||||
id = e.srcElement.id
|
||||
}
|
||||
if (id) {
|
||||
contextMenuVisible.value = true
|
||||
let width
|
||||
if (isCollapse.value) {
|
||||
width = 54
|
||||
} else {
|
||||
width = 220
|
||||
}
|
||||
if (isMobile.value) {
|
||||
width = 0
|
||||
}
|
||||
left.value = e.clientX - width
|
||||
top.value = e.clientY + 10
|
||||
rightActive.value = id.substring(4)
|
||||
}
|
||||
}
|
||||
const closeAll = () => {
|
||||
historys.value = [
|
||||
{
|
||||
name: defaultRouter.value,
|
||||
meta: {
|
||||
title: '首页',
|
||||
},
|
||||
query: {},
|
||||
params: {},
|
||||
},
|
||||
]
|
||||
router.push({ name: defaultRouter.value })
|
||||
contextMenuVisible.value = false
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
}
|
||||
const closeLeft = () => {
|
||||
let right
|
||||
const rightIndex = historys.value.findIndex((item) => {
|
||||
if (getFmtString(item) === rightActive.value) {
|
||||
right = item
|
||||
}
|
||||
return getFmtString(item) === rightActive.value
|
||||
})
|
||||
const activeIndex = historys.value.findIndex(
|
||||
(item) => getFmtString(item) === activeValue.value
|
||||
)
|
||||
historys.value.splice(0, rightIndex)
|
||||
if (rightIndex > activeIndex) {
|
||||
router.push(right)
|
||||
}
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
}
|
||||
const closeRight = () => {
|
||||
let right
|
||||
const leftIndex = historys.value.findIndex((item) => {
|
||||
if (getFmtString(item) === rightActive.value) {
|
||||
right = item
|
||||
}
|
||||
return getFmtString(item) === rightActive.value
|
||||
})
|
||||
const activeIndex = historys.value.findIndex(
|
||||
(item) => getFmtString(item) === activeValue.value
|
||||
)
|
||||
historys.value.splice(leftIndex + 1, historys.value.length)
|
||||
if (leftIndex < activeIndex) {
|
||||
router.push(right)
|
||||
}
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
}
|
||||
const closeOther = () => {
|
||||
let right
|
||||
historys.value = historys.value.filter((item) => {
|
||||
if (getFmtString(item) === rightActive.value) {
|
||||
right = item
|
||||
}
|
||||
return getFmtString(item) === rightActive.value
|
||||
})
|
||||
router.push(right)
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
}
|
||||
const isSame = (route1, route2) => {
|
||||
if (route1.name !== route2.name) {
|
||||
return false
|
||||
}
|
||||
if (Object.keys(route1.query).length !== Object.keys(route2.query).length || Object.keys(route1.params).length !== Object.keys(route2.params).length) {
|
||||
return false
|
||||
}
|
||||
for (const key in route1.query) {
|
||||
if (route1.query[key] !== route2.query[key]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for (const key in route1.params) {
|
||||
if (route1.params[key] !== route2.params[key]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
const setTab = (route) => {
|
||||
if (!historys.value.some((item) => isSame(item, route))) {
|
||||
const obj = {}
|
||||
obj.name = route.name
|
||||
obj.meta = { ...route.meta }
|
||||
delete obj.meta.matched
|
||||
obj.query = route.query
|
||||
obj.params = route.params
|
||||
historys.value.push(obj)
|
||||
}
|
||||
window.sessionStorage.setItem('activeValue', getFmtString(route))
|
||||
}
|
||||
|
||||
const historyMap = ref({})
|
||||
|
||||
const changeTab = (TabsPaneContext) => {
|
||||
const name = TabsPaneContext?.props?.name
|
||||
if (!name) return
|
||||
const tab = historyMap.value[name]
|
||||
router.push({
|
||||
name: tab.name,
|
||||
query: tab.query,
|
||||
params: tab.params,
|
||||
})
|
||||
}
|
||||
const removeTab = (tab) => {
|
||||
const index = historys.value.findIndex(
|
||||
(item) => getFmtString(item) === tab
|
||||
)
|
||||
if (getFmtString(route) === tab) {
|
||||
if (historys.value.length === 1) {
|
||||
router.push({ name: defaultRouter.value })
|
||||
} else {
|
||||
if (index < historys.value.length - 1) {
|
||||
router.push({
|
||||
name: historys.value[index + 1].name,
|
||||
query: historys.value[index + 1].query,
|
||||
params: historys.value[index + 1].params,
|
||||
})
|
||||
} else {
|
||||
router.push({
|
||||
name: historys.value[index - 1].name,
|
||||
query: historys.value[index - 1].query,
|
||||
params: historys.value[index - 1].params,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
historys.value.splice(index, 1)
|
||||
}
|
||||
|
||||
watch(() => contextMenuVisible.value, () => {
|
||||
if (contextMenuVisible.value) {
|
||||
document.body.addEventListener('click', () => {
|
||||
contextMenuVisible.value = false
|
||||
})
|
||||
} else {
|
||||
document.body.removeEventListener('click', () => {
|
||||
contextMenuVisible.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => route, (to, now) => {
|
||||
if (to.name === 'Login' || to.name === 'Reload') {
|
||||
return
|
||||
}
|
||||
historys.value = historys.value.filter((item) => !item.meta.closeTab)
|
||||
setTab(to)
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
activeValue.value = window.sessionStorage.getItem('activeValue')
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => historys.value, () => {
|
||||
sessionStorage.setItem('historys', JSON.stringify(historys.value))
|
||||
historyMap.value = {}
|
||||
historys.value.forEach((item) => {
|
||||
historyMap.value[getFmtString(item)] = item
|
||||
})
|
||||
emitter.emit('setKeepAlive', historys.value)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
const initPage = () => {
|
||||
// 全局监听 关闭当前页面函数
|
||||
emitter.on('closeThisPage', () => {
|
||||
removeTab(name(route))
|
||||
})
|
||||
// 全局监听 关闭所有页面函数
|
||||
emitter.on('closeAllPage', () => {
|
||||
closeAll()
|
||||
})
|
||||
emitter.on('mobile', (data) => {
|
||||
isMobile.value = data
|
||||
})
|
||||
emitter.on('collapse', (data) => {
|
||||
isCollapse.value = data
|
||||
})
|
||||
const initHistorys = [
|
||||
{
|
||||
name: defaultRouter.value,
|
||||
meta: {
|
||||
title: '首页',
|
||||
},
|
||||
query: {},
|
||||
params: {},
|
||||
},
|
||||
]
|
||||
historys.value =
|
||||
JSON.parse(sessionStorage.getItem('historys')) || initHistorys
|
||||
if (!window.sessionStorage.getItem('activeValue')) {
|
||||
activeValue.value = getFmtString(route)
|
||||
} else {
|
||||
activeValue.value = window.sessionStorage.getItem('activeValue')
|
||||
}
|
||||
setTab(route)
|
||||
if (window.sessionStorage.getItem('needCloseAll') === 'true') {
|
||||
closeAll()
|
||||
window.sessionStorage.removeItem('needCloseAll')
|
||||
}
|
||||
}
|
||||
initPage()
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off('collapse')
|
||||
emitter.off('mobile')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.contextmenu {
|
||||
width: 100px;
|
||||
margin: 0;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.el-tabs__item .el-icon-close {
|
||||
color: initial !important;
|
||||
}
|
||||
.el-tabs__item .dot {
|
||||
content: "";
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
margin-right: 8px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.contextmenu li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
}
|
||||
.contextmenu li:hover {
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
151
src/view/layout/aside/index.vue
Normal file
151
src/view/layout/aside/index.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div :style="{ background: userStore.sideMode }">
|
||||
<el-scrollbar style="height: calc(100vh - 60px)">
|
||||
<transition
|
||||
:duration="{ enter: 800, leave: 100 }"
|
||||
mode="out-in"
|
||||
name="el-fade-in-linear"
|
||||
>
|
||||
<el-menu
|
||||
:collapse="isCollapse"
|
||||
:collapse-transition="false"
|
||||
:default-active="active"
|
||||
:background-color="theme.background"
|
||||
:active-text-color="theme.active"
|
||||
class="el-menu-vertical"
|
||||
unique-opened
|
||||
@select="selectMenuItem"
|
||||
>
|
||||
<template v-for="item in routerStore.asyncRouters[0].children">
|
||||
<aside-component
|
||||
v-if="!item.hidden"
|
||||
:key="item.name"
|
||||
:is-collapse="isCollapse"
|
||||
:router-info="item"
|
||||
:theme="theme"
|
||||
/>
|
||||
</template>
|
||||
</el-menu>
|
||||
</transition>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Aside',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import AsideComponent from '@/view/layout/aside/asideComponent/index.vue'
|
||||
import { emitter } from '@/utils/bus.js'
|
||||
import { ref, watch, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/pinia/modules/user'
|
||||
import { useRouterStore } from '@/pinia/modules/router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const routerStore = useRouterStore()
|
||||
|
||||
const theme = ref({})
|
||||
|
||||
const getTheme = () => {
|
||||
switch (userStore.sideMode) {
|
||||
case '#fff':
|
||||
theme.value = {
|
||||
background: '#fff',
|
||||
activeBackground: '#4D70FF',
|
||||
activeText: '#fff',
|
||||
normalText: '#333',
|
||||
hoverBackground: 'rgba(64, 158, 255, 0.08)',
|
||||
hoverText: '#333',
|
||||
}
|
||||
break
|
||||
case '#191a23':
|
||||
theme.value = {
|
||||
background: '#191a23',
|
||||
activeBackground: '#4D70FF',
|
||||
activeText: '#fff',
|
||||
normalText: '#fff',
|
||||
hoverBackground: 'rgba(64, 158, 255, 0.08)',
|
||||
hoverText: '#fff',
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
getTheme()
|
||||
|
||||
const active = ref('')
|
||||
watch(() => route, () => {
|
||||
active.value = route.meta.activeName || route.name
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => userStore.sideMode, () => {
|
||||
getTheme()
|
||||
})
|
||||
|
||||
const isCollapse = ref(false)
|
||||
const initPage = () => {
|
||||
active.value = route.meta.activeName || route.name
|
||||
const screenWidth = document.body.clientWidth
|
||||
if (screenWidth < 1000) {
|
||||
isCollapse.value = !isCollapse.value
|
||||
}
|
||||
|
||||
emitter.on('collapse', (item) => {
|
||||
isCollapse.value = item
|
||||
})
|
||||
}
|
||||
|
||||
initPage()
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off('collapse')
|
||||
})
|
||||
|
||||
const selectMenuItem = (index, _, ele, aaa) => {
|
||||
const query = {}
|
||||
const params = {}
|
||||
routerStore.routeMap[index]?.parameters &&
|
||||
routerStore.routeMap[index]?.parameters.forEach((item) => {
|
||||
if (item.type === 'query') {
|
||||
query[item.key] = item.value
|
||||
} else {
|
||||
params[item.key] = item.value
|
||||
}
|
||||
})
|
||||
if (index === route.name) return
|
||||
if (index.indexOf('http://') > -1 || index.indexOf('https://') > -1) {
|
||||
window.open(index)
|
||||
} else {
|
||||
router.push({ name: index, query, params })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.el-sub-menu__title:hover,
|
||||
.el-menu-item:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
.el-scrollbar__view {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.menu-info {
|
||||
.menu-contorl {
|
||||
line-height: 52px;
|
||||
font-size: 20px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user