refactor: 重构header

This commit is contained in:
张传龙 2022-05-11 14:54:12 +08:00
parent 2338ded165
commit 958589edd0
7 changed files with 99 additions and 123 deletions

View File

@ -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 IconMenuCollapse } from '~icons/mdi/format-indent-decrease'
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 IconFullscreenExit } from '~icons/ant-design/fullscreen-exit-outlined'

View File

@ -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>

View File

@ -7,8 +7,7 @@
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
import { router } from '@/router'
const { currentRoute } = router
function handleBreadClick(path) {

View 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>

View 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>

View 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>

View File

@ -1,24 +1,21 @@
<template>
<header class="header">
<div class="h-left">
<n-icon size="20" style="cursor: pointer" @click="appStore.switchCollapsed">
<IconMenuExpand v-if="appStore.collapsed" />
<IconMenuCollapse v-else />
</n-icon>
<MenuCollapse />
<BreadCrumb ml-15 />
</div>
<HeaderAction />
<div class="h-right">
<FullScreen />
<UserAvatar />
</div>
</header>
</template>
<script setup>
import { useAppStore } from '@/store/modules/app'
import BreadCrumb from './BreadCrumb.vue'
import HeaderAction from './HeaderAction.vue'
import { IconMenuCollapse, IconMenuExpand } from '@/components/AppIcons'
const appStore = useAppStore()
import BreadCrumb from './components/BreadCrumb.vue'
import MenuCollapse from './components/MenuCollapse.vue'
import FullScreen from './components/FullScreen.vue'
import UserAvatar from './components/UserAvatar.vue'
</script>
<style lang="scss" scoped>
@ -32,5 +29,9 @@ const appStore = useAppStore()
display: flex;
align-items: center;
}
.h-right {
display: flex;
align-items: center;
}
}
</style>