refactor: 重构header
This commit is contained in:
parent
2338ded165
commit
958589edd0
@ -16,6 +16,7 @@ export { default as IconExpandRight } from '~icons/mdi/arrow-expand-right'
|
|||||||
export { default as IconMenuTable } from '~icons/mdi/table'
|
export { default as IconMenuTable } from '~icons/mdi/table'
|
||||||
export { default as IconMenuCollapse } from '~icons/mdi/format-indent-decrease'
|
export { default as IconMenuCollapse } from '~icons/mdi/format-indent-decrease'
|
||||||
export { default as IconMenuExpand } from '~icons/mdi/format-indent-increase'
|
export { default as IconMenuExpand } from '~icons/mdi/format-indent-increase'
|
||||||
|
export { default as IconExit } from '~icons/mdi/exit-to-app'
|
||||||
|
|
||||||
export { default as IconFullscreen } from '~icons/ant-design/fullscreen-outlined'
|
export { default as IconFullscreen } from '~icons/ant-design/fullscreen-outlined'
|
||||||
export { default as IconFullscreenExit } from '~icons/ant-design/fullscreen-exit-outlined'
|
export { default as IconFullscreenExit } from '~icons/ant-design/fullscreen-exit-outlined'
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="actions-wrapper">
|
|
||||||
<n-icon mr20 size="18" style="cursor: pointer" @click="toggle">
|
|
||||||
<IconFullscreenExit v-if="isFullscreen" />
|
|
||||||
<IconFullscreen v-else />
|
|
||||||
</n-icon>
|
|
||||||
<n-dropdown :options="options" @select="handleSelect">
|
|
||||||
<div class="avatar">
|
|
||||||
<img :src="userStore.avatar" />
|
|
||||||
<span>{{ userStore.name }}</span>
|
|
||||||
</div>
|
|
||||||
</n-dropdown>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { IconFullscreen, IconFullscreenExit } from '@/components/AppIcons'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { resetRouter } from '@/router'
|
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
|
||||||
import { NOT_FOUND_ROUTE } from '@/router/routes'
|
|
||||||
import { useFullscreen } from '@vueuse/core'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const router = useRouter()
|
|
||||||
const { isFullscreen, toggle } = useFullscreen()
|
|
||||||
|
|
||||||
const options = [
|
|
||||||
{
|
|
||||||
label: '切换角色',
|
|
||||||
key: 'switchRole',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '退出登录',
|
|
||||||
key: 'logout',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
function handleSelect(key) {
|
|
||||||
if (key === 'logout') {
|
|
||||||
logout()
|
|
||||||
} else if (key === 'switchRole') {
|
|
||||||
switchRole()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function logout() {
|
|
||||||
userStore.logout()
|
|
||||||
$message.success('已退出登录')
|
|
||||||
router.push({ path: '/login' })
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchRole() {
|
|
||||||
const permissionStore = usePermissionStore()
|
|
||||||
|
|
||||||
const users = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: '大脸怪(admin)',
|
|
||||||
avatar: 'https://assets.qszone.com/images/avatar.jpg',
|
|
||||||
email: 'Ronnie@123.com',
|
|
||||||
role: ['admin'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: '大脸怪(editor)',
|
|
||||||
avatar: 'https://assets.qszone.com/images/avatar.jpg',
|
|
||||||
email: 'Ronnie@123.com',
|
|
||||||
role: ['editor'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: '访客(guest)',
|
|
||||||
avatar: 'https://assets.qszone.com/images/avatar.jpg',
|
|
||||||
role: [],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const switchUser = users[+userStore.userId % users.length]
|
|
||||||
resetRouter()
|
|
||||||
userStore.setUserInfo(switchUser)
|
|
||||||
const accessRoutes = permissionStore.generateRoutes(switchUser.role)
|
|
||||||
accessRoutes.forEach((route) => {
|
|
||||||
!router.hasRoute(route.name) && router.addRoute(route)
|
|
||||||
})
|
|
||||||
router.addRoute(NOT_FOUND_ROUTE)
|
|
||||||
$message.success(`${switchUser.name}`)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.actions-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
width: 25px;
|
|
||||||
height: 25px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -7,8 +7,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useRouter } from 'vue-router'
|
import { router } from '@/router'
|
||||||
const router = useRouter()
|
|
||||||
const { currentRoute } = router
|
const { currentRoute } = router
|
||||||
|
|
||||||
function handleBreadClick(path) {
|
function handleBreadClick(path) {
|
15
src/layout/components/header/components/FullScreen.vue
Normal file
15
src/layout/components/header/components/FullScreen.vue
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<n-icon mr20 size="18" style="cursor: pointer" @click="toggle">
|
||||||
|
<IconFullscreenExit v-if="isFullscreen" />
|
||||||
|
<IconFullscreen v-else />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { IconFullscreen, IconFullscreenExit } from '@/components/AppIcons'
|
||||||
|
import { useFullscreen } from '@vueuse/core'
|
||||||
|
|
||||||
|
const { isFullscreen, toggle } = useFullscreen()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
15
src/layout/components/header/components/MenuCollapse.vue
Normal file
15
src/layout/components/header/components/MenuCollapse.vue
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<n-icon size="20" style="cursor: pointer" @click="appStore.switchCollapsed">
|
||||||
|
<IconMenuExpand v-if="appStore.collapsed" />
|
||||||
|
<IconMenuCollapse v-else />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { IconMenuCollapse, IconMenuExpand } from '@/components/AppIcons'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
54
src/layout/components/header/components/UserAvatar.vue
Normal file
54
src/layout/components/header/components/UserAvatar.vue
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<n-dropdown :options="options" @select="handleSelect">
|
||||||
|
<div class="avatar">
|
||||||
|
<img :src="userStore.avatar" />
|
||||||
|
<span>{{ userStore.name }}</span>
|
||||||
|
</div>
|
||||||
|
</n-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { router } from '@/router'
|
||||||
|
import { useUserStore } from '@/store/modules/user'
|
||||||
|
import { IconExit } from '@/components/AppIcons'
|
||||||
|
import { renderIcon } from '@/utils/icon'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: '退出登录',
|
||||||
|
key: 'logout',
|
||||||
|
icon: renderIcon(IconExit, { size: '14px' }),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
function handleSelect(key) {
|
||||||
|
console.log(router)
|
||||||
|
if (key === 'logout') {
|
||||||
|
$dialog.confirm({
|
||||||
|
content: '确认退出?',
|
||||||
|
confirm() {
|
||||||
|
userStore.logout()
|
||||||
|
$message.success('已退出登录')
|
||||||
|
router.push({ path: '/login' })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.avatar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,24 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="h-left">
|
<div class="h-left">
|
||||||
<n-icon size="20" style="cursor: pointer" @click="appStore.switchCollapsed">
|
<MenuCollapse />
|
||||||
<IconMenuExpand v-if="appStore.collapsed" />
|
|
||||||
<IconMenuCollapse v-else />
|
|
||||||
</n-icon>
|
|
||||||
<BreadCrumb ml-15 />
|
<BreadCrumb ml-15 />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="h-right">
|
||||||
<HeaderAction />
|
<FullScreen />
|
||||||
|
<UserAvatar />
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import BreadCrumb from './components/BreadCrumb.vue'
|
||||||
import BreadCrumb from './BreadCrumb.vue'
|
import MenuCollapse from './components/MenuCollapse.vue'
|
||||||
import HeaderAction from './HeaderAction.vue'
|
import FullScreen from './components/FullScreen.vue'
|
||||||
import { IconMenuCollapse, IconMenuExpand } from '@/components/AppIcons'
|
import UserAvatar from './components/UserAvatar.vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -32,5 +29,9 @@ const appStore = useAppStore()
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.h-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user