chore: rename some layout components; 🐶

This commit is contained in:
iczer
2020-06-29 19:17:51 +08:00
parent 2eafdef2f9
commit fc0101f4e3
16 changed files with 286 additions and 509 deletions

View File

@@ -0,0 +1,165 @@
<template>
<a-layout-header :class="[headerTheme, 'admin-header']">
<div :class="['admin-header-wide', layout]">
<router-link v-if="isMobile || layout === 'head'" to="/" :class="['logo', isMobile ? null : 'pc', headerTheme]">
<img width="32" src="@/assets/img/logo.png" />
<h1 v-if="!isMobile">{{systemName}}</h1>
</router-link>
<a-divider v-if="isMobile" type="vertical" />
<a-icon v-if="layout === 'side'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/>
<div v-if="layout == 'head' && !isMobile" class="admin-header-menu">
<i-menu style="height: 64px; line-height: 64px;" @i18nComplete="setRoutesI18n" :i18n="menuI18n" :theme="headerTheme" mode="horizontal" :options="menuData" @select="onSelect"/>
</div>
<div :class="['admin-header-right', headerTheme]">
<header-search class="header-item" />
<a-tooltip class="header-item" title="帮助文档" placement="bottom" >
<a>
<a-icon type="question-circle-o" />
</a>
</a-tooltip>
<header-notice class="header-item"/>
<header-avatar class="header-item"/>
<a-dropdown class="lang header-item">
<div>
<a-icon type="global"/> {{langAlias}}
</div>
<a-menu @click="val => setLang(val.key)" :selected-keys="[lang]" slot="overlay">
<a-menu-item v-for=" lang in langList" :key="lang.key">{{lang.key.toLowerCase() + ' ' + lang.name}}</a-menu-item>
</a-menu>
</a-dropdown>
</div>
</div>
</a-layout-header>
</template>
<script>
import HeaderSearch from './HeaderSearch'
import HeaderNotice from './HeaderNotice'
import HeaderAvatar from './HeaderlAvatar'
import IMenu from '@/components/menu/menu'
import {mapState, mapMutations} from 'vuex'
export default {
name: 'AdminHeader',
components: {IMenu, HeaderAvatar, HeaderNotice, HeaderSearch},
props: ['collapsed', 'menuData'],
inject: ['menuI18n'],
data() {
return {
langList: [
{key: 'CN', name: '简体中文', alias: '简体'},
{key: 'HK', name: '繁體中文', alias: '繁體'},
{key: 'US', name: 'English', alias: 'English'}
]
}
},
computed: {
...mapState('setting', ['theme', 'isMobile', 'layout', 'systemName', 'lang']),
headerTheme () {
return (this.layout == 'side' && !this.isMobile) ? 'light' : this.theme
},
langAlias() {
let lang = this.langList.find(item => item.key == this.lang)
return lang.alias
}
},
methods: {
toggleCollapse () {
this.$emit('toggleCollapse')
},
onSelect (obj) {
this.$emit('menuSelect', obj)
},
...mapMutations('setting', ['setLang', 'setRoutesI18n'])
}
}
</script>
<style lang="less" scoped>
.trigger {
font-size: 20px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color .3s;
&:hover{
color: #1890ff;
}
}
.admin-header{
padding: 0;
-webkit-box-shadow: 0 1px 4px rgba(0,21,41,.08);
box-shadow: 0 1px 4px rgba(0,21,41,.08);
z-index: 1;
position: relative;
&.light{
background: #fff;
}
&.dark{
background: #001529;
.trigger{
color: white;
}
}
.admin-header-wide{
&.head{
max-width: 1400px;
margin: auto;
}
&.side{
padding-right: 12px;
}
.logo {
height: 64px;
line-height: 58px;
vertical-align: top;
display: inline-block;
padding: 0 12px 0 24px;
cursor: pointer;
font-size: 20px;
&.pc{
padding: 0 12px 0 0;
}
img {
display: inline-block;
vertical-align: middle;
}
h1{
display: inline-block;
font-size: 16px;
}
&.dark h1{
color: #fff;
}
}
.admin-header-menu{
display: inline-block;
}
.admin-header-right{
float: right;
display: flex;
&.dark{
color: #fff;
a, i{
color: #fff !important;
}
.header-item:hover{
background-color: @primary-color;
}
}
.header-item{
padding: 0 12px;
cursor: pointer;
align-self: center;
&:hover{
background-color: @gray-3;
}
i{
font-size: 16px;
color: rgba(0,0,0,.65);
}
}
}
}
}
</style>

View File

@@ -0,0 +1,88 @@
<template>
<a-dropdown :trigger="['click']" v-model="show">
<div slot="overlay">
<a-spin :spinning="loading">
<a-tabs class="dropdown-tabs" :tabBarStyle="{textAlign: 'center'}" :style="{backgroundColor: 'white', width: '297px'}">
<a-tab-pane tab="通知" key="1">
<a-list class="tab-pane">
<a-list-item>
<a-list-item-meta title="你收到了 14 份新周报" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta title="你推荐的 曲妮妮 已通过第三轮面试" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta title="这种模板可以区分多种通知类型" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/>
</a-list-item-meta>
</a-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane tab="消息" key="2">
<a-list class="tab-pane"></a-list>
</a-tab-pane>
<a-tab-pane tab="待办" key="3">
<a-list class="tab-pane"></a-list>
</a-tab-pane>
</a-tabs>
</a-spin>
</div>
<span @click="fetchNotice" class="header-notice">
<a-badge count="12">
<a-icon :class="['header-notice-icon']" type="bell" />
</a-badge>
</span>
</a-dropdown>
</template>
<script>
export default {
name: 'HeaderNotice',
data () {
return {
loading: false,
show: false
}
},
computed: {
},
methods: {
fetchNotice () {
if (this.loading) {
this.loading = false
return
}
this.loadding = true
setTimeout(() => {
this.loadding = false
}, 1000)
}
}
}
</script>
<style lang="less" scoped>
.header-notice{
display: inline-block;
transition: all 0.3s;
span {
vertical-align: initial;
}
.header-notice-icon{
font-size: 16px;
padding: 4px;
}
}
.dropdown-tabs{
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border-radius: 4px;
.tab-pane{
padding: 0 24px 12px;
min-height: 250px;
}
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<div class="header-search">
<a-icon type="search" class="search-icon" @click="enterSearchMode"/>
<a-auto-complete
ref="input"
:dataSource="dataSource"
:class="['search-input', searchMode ? 'enter' : 'leave']"
placeholder="站内搜索"
@blur="leaveSearchMode"
>
</a-auto-complete>
</div>
</template>
<script>
export default {
name: 'HeaderSearch',
data () {
return {
dataSource: ['选项一', '选项二'],
searchMode: false
}
},
methods: {
enterSearchMode () {
this.searchMode = true
setTimeout(() => this.$refs.input.focus(), 300)
},
leaveSearchMode () {
this.searchMode = false
}
}
}
</script>
<style lang="less">
.header-search{
.search-icon{
font-size: 16px;
cursor: pointer;
}
.search-input{
border: 0;
border-bottom: 1px rgba(3, 5, 6, 0.23) solid;
transition: width 0.3s ease-in-out;
input{
border: 0;
box-shadow: 0 0 0 0;
}
&.leave{
width: 0px;
input{
display: none;
}
}
&.enter{
width: 200px;
input:focus{
box-shadow: 0 0 0 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<a-dropdown>
<div class="header-avatar" style="cursor: pointer">
<a-avatar class="avatar" size="small" shape="circle" :src="user.avatar"/>
<span class="name">{{user.name}}</span>
</div>
<a-menu :class="['avatar-menu']" slot="overlay">
<a-menu-item>
<a-icon type="user" />
<span>个人中心</span>
</a-menu-item>
<a-menu-item>
<a-icon type="setting" />
<span>设置</span>
</a-menu-item>
<a-menu-divider />
<a-menu-item>
<router-link to="/login">
<a-icon type="poweroff" />
<span>退出登录</span>
</router-link>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'HeaderAvatar',
computed: {
...mapState('setting', ['weekMode']),
...mapState('account', ['user']),
}
}
</script>
<style lang="less">
.header-avatar{
display: inline-flex;
.avatar, .name{
align-self: center;
}
.avatar{
margin-right: 8px;
}
.name{
font-weight: 500;
}
}
.avatar-menu{
width: 150px;
}
</style>