refactor: update to new project structure
This commit is contained in:
44
src/layouts/GlobalFooter.vue
Normal file
44
src/layouts/GlobalFooter.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="footer">
|
||||
<div class="links">
|
||||
<a target="_blank" :key="index" :href="item.link ? item.link : 'javascript: void(0)'" v-for="(item, index) in linkList">
|
||||
<a-icon v-if="item.icon" :type="item.icon"/>{{item.name}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
Copyright<a-icon type="copyright" />{{copyright}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
export default {
|
||||
name: 'GlobalFooter',
|
||||
props: ['copyright', 'linkList'],
|
||||
components: {AIcon}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.footer{
|
||||
padding: 0 16px;
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
.copyright{
|
||||
color: rgba(0,0,0,.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
.links{
|
||||
margin-bottom: 8px;
|
||||
a:not(:last-child) {
|
||||
margin-right: 40px;
|
||||
}
|
||||
a{
|
||||
color: rgba(0,0,0,.45);
|
||||
-webkit-transition: all .3s;
|
||||
transition: all .3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
157
src/layouts/GlobalHeader.vue
Normal file
157
src/layouts/GlobalHeader.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<a-layout-header :class="[theme, 'global-header']">
|
||||
<div :class="['global-header-wide', layout]">
|
||||
<router-link v-if="isMobile || layout === 'head'" to="/" :class="['logo', isMobile ? null : 'pc', theme]">
|
||||
<img width="32" src="static/img/vue-antd-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'" class="global-header-menu">
|
||||
<i-menu style="height: 64px; line-height: 64px;" :theme="theme" mode="horizontal" :menuData="menuData" @select="onSelect"/>
|
||||
</div>
|
||||
<div :class="['global-header-right', theme]">
|
||||
<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"/>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ALayout from 'ant-design-vue/es/layout'
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
import AInputSearch from 'ant-design-vue/es/input/Search'
|
||||
import HeaderSearch from './HeaderSearch'
|
||||
import HeaderNotice from './HeaderNotice'
|
||||
import ATooltip from 'ant-design-vue/es/tooltip/Tooltip'
|
||||
import HeaderAvatar from './HeaderlAvatar'
|
||||
import ADivider from 'ant-design-vue/es/divider/index'
|
||||
import IMenu from '../components/menu/menu'
|
||||
|
||||
const ALayoutSider = ALayout.Sider
|
||||
const ALayoutHeader = ALayout.Header
|
||||
export default {
|
||||
name: 'GlobalHeader',
|
||||
components: {
|
||||
IMenu,
|
||||
ADivider,
|
||||
HeaderAvatar,
|
||||
ATooltip,
|
||||
HeaderNotice,
|
||||
HeaderSearch,
|
||||
AInputSearch,
|
||||
AIcon,
|
||||
ALayout,
|
||||
ALayoutSider,
|
||||
ALayoutHeader},
|
||||
props: ['collapsed', 'menuData'],
|
||||
computed: {
|
||||
isMobile () {
|
||||
return this.$store.state.setting.isMobile
|
||||
},
|
||||
layout () {
|
||||
return this.$store.state.setting.layout
|
||||
},
|
||||
theme () {
|
||||
return this.layout === 'side' ? 'light' : this.$store.state.setting.theme
|
||||
},
|
||||
systemName () {
|
||||
return this.$store.state.setting.systemName
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleCollapse () {
|
||||
this.$emit('toggleCollapse')
|
||||
},
|
||||
onSelect (obj) {
|
||||
this.$emit('menuSelect', obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.trigger {
|
||||
font-size: 20px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
&:hover{
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
.header-item{
|
||||
padding: 0 12px;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
i{
|
||||
font-size: 16px;
|
||||
color: rgba(0,0,0,.65);
|
||||
}
|
||||
}
|
||||
.global-header{
|
||||
padding: 0 12px 0 0;
|
||||
-webkit-box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
position: relative;
|
||||
&.light{
|
||||
background: #fff;
|
||||
}
|
||||
&.dark{
|
||||
background: #001529;
|
||||
}
|
||||
.global-header-wide{
|
||||
&.head{
|
||||
max-width: 1400px;
|
||||
margin: auto;
|
||||
}
|
||||
&.side{
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
.global-header-menu{
|
||||
display: inline-block;
|
||||
}
|
||||
.global-header-right{
|
||||
float: right;
|
||||
&.dark{
|
||||
color: #fff;
|
||||
i{
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
112
src/layouts/GlobalLayout.vue
Normal file
112
src/layouts/GlobalLayout.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<a-layout>
|
||||
<drawer v-if="isMobile" :openDrawer="collapsed" @change="onDrawerChange">
|
||||
<sider-menu :theme="theme" :menuData="menuData" :collapsed="false" :collapsible="false" @menuSelect="onMenuSelect"/>
|
||||
</drawer>
|
||||
<sider-menu :theme="theme" v-else-if="layout === 'side'" :menuData="menuData" :collapsed="collapsed" :collapsible="true" />
|
||||
<drawer :open-drawer="showSetting" placement="right" @change="onSettingDrawerChange">
|
||||
<div class="setting" slot="handler">
|
||||
<a-icon :type="showSetting ? 'close' : 'setting'" />
|
||||
</div>
|
||||
<setting />
|
||||
</drawer>
|
||||
<a-layout>
|
||||
<global-header :menuData="menuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
|
||||
<a-layout-content :style="{minHeight: minHeight, margin: '24px 24px 0'}">
|
||||
<slot></slot>
|
||||
</a-layout-content>
|
||||
<a-layout-footer style="padding: 0px">
|
||||
<global-footer :link-list="linkList" :copyright="copyright" />
|
||||
</a-layout-footer>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ALayout from 'ant-design-vue/es/layout'
|
||||
import GlobalHeader from './GlobalHeader'
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
import GlobalFooter from './GlobalFooter'
|
||||
import Drawer from '../components/tool/Drawer'
|
||||
import SiderMenu from '../components/menu/SiderMenu'
|
||||
import Setting from '../components/setting/Setting'
|
||||
|
||||
const ALayoutSider = ALayout.Sider
|
||||
const ALayoutHeader = ALayout.Header
|
||||
const ALayoutContent = ALayout.Content
|
||||
const ALayoutFooter = ALayout.Footer
|
||||
const minHeight = window.innerHeight - 64 - 24 - 122
|
||||
|
||||
let menuData = []
|
||||
|
||||
export default {
|
||||
name: 'GlobalLayout',
|
||||
components: {
|
||||
Setting,
|
||||
SiderMenu,
|
||||
Drawer,
|
||||
GlobalFooter,
|
||||
AIcon,
|
||||
GlobalHeader,
|
||||
ALayout,
|
||||
ALayoutSider,
|
||||
ALayoutHeader,
|
||||
ALayoutContent,
|
||||
ALayoutFooter},
|
||||
data () {
|
||||
return {
|
||||
minHeight: minHeight + 'px',
|
||||
collapsed: false,
|
||||
menuData: menuData,
|
||||
showSetting: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isMobile () {
|
||||
return this.$store.state.setting.isMobile
|
||||
},
|
||||
theme () {
|
||||
return this.$store.state.setting.theme
|
||||
},
|
||||
layout () {
|
||||
return this.$store.state.setting.layout
|
||||
},
|
||||
linkList () {
|
||||
return this.$store.state.setting.footerLinks
|
||||
},
|
||||
copyright () {
|
||||
return this.$store.state.setting.copyright
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleCollapse () {
|
||||
this.collapsed = !this.collapsed
|
||||
},
|
||||
onDrawerChange (show) {
|
||||
this.collapsed = show
|
||||
},
|
||||
onMenuSelect () {
|
||||
this.toggleCollapse()
|
||||
},
|
||||
onSettingDrawerChange (val) {
|
||||
this.showSetting = val
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
menuData = this.$router.options.routes.find((item) => item.path === '/').children
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.setting{
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
border-radius: 5px 0 0 5px;
|
||||
line-height: 40px;
|
||||
font-size: 22px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
</style>
|
||||
101
src/layouts/HeaderNotice.vue
Normal file
101
src/layouts/HeaderNotice.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<a-popover trigger="click" placement="bottomRight">
|
||||
<template slot="content">
|
||||
<a-spin :spinning="loadding">
|
||||
<a-tabs>
|
||||
<a-tab-pane tab="通知" key="1">
|
||||
<a-list>
|
||||
<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">
|
||||
123
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="待办" key="3">
|
||||
123
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-spin>
|
||||
</template>
|
||||
<span @click="fetchNotice" class="header-notice">
|
||||
<a-badge count="12">
|
||||
<a-icon :class="['header-notice-icon', theme]" type="bell" />
|
||||
</a-badge>
|
||||
</span>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import APopover from 'ant-design-vue/es/popover/index'
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
import ABadge from 'ant-design-vue/es/badge/Badge'
|
||||
import ATabs from 'ant-design-vue/es/tabs'
|
||||
import AList from 'ant-design-vue/es/list/index'
|
||||
import AListItem from 'ant-design-vue/es/list/Item'
|
||||
import AAvatar from 'ant-design-vue/es/avatar/Avatar'
|
||||
import ASpin from 'ant-design-vue/es/spin/Spin'
|
||||
|
||||
const ATabPane = ATabs.TabPane
|
||||
const AListItemMeta = AListItem.Meta
|
||||
|
||||
export default {
|
||||
name: 'HeaderNotice',
|
||||
components: {ASpin, AAvatar, AListItem, AList, ATabs, ABadge, AIcon, APopover, ATabPane, AListItemMeta},
|
||||
data () {
|
||||
return {
|
||||
loadding: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
theme () {
|
||||
return this.$store.state.setting.layout === 'side' ? 'light' : this.$store.state.setting.theme
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchNotice () {
|
||||
if (this.loadding) {
|
||||
this.loadding = false
|
||||
return
|
||||
}
|
||||
this.loadding = true
|
||||
setTimeout(() => {
|
||||
this.loadding = false
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.header-notice{
|
||||
display: inline-block;
|
||||
transition: all 0.3s;
|
||||
span {
|
||||
vertical-align: initial;
|
||||
}
|
||||
.header-notice-icon{
|
||||
font-size: 16px;
|
||||
padding: 4px;
|
||||
&.dark{
|
||||
color: #fff;
|
||||
}
|
||||
&.light{
|
||||
color: rgba(0,0,0,.65);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
68
src/layouts/HeaderSearch.vue
Normal file
68
src/layouts/HeaderSearch.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<span 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>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
import AAutoComplete from 'ant-design-vue/es/auto-complete/index'
|
||||
import AInput from 'ant-design-vue/es/input/Input'
|
||||
export default {
|
||||
name: 'HeaderSearch',
|
||||
components: {AInput, AAutoComplete, AIcon},
|
||||
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>
|
||||
54
src/layouts/HeaderlAvatar.vue
Normal file
54
src/layouts/HeaderlAvatar.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<a-dropdown style="display: inline-block; height: 100%; vertical-align: initial" >
|
||||
<span style="cursor: pointer">
|
||||
<a-avatar class="avatar" size="small" shape="circle" :src="currUser.avatar"/>
|
||||
<span>{{currUser.name}}</span>
|
||||
</span>
|
||||
<a-menu style="width: 150px" 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 ADropdown from 'ant-design-vue/es/dropdown'
|
||||
import AAvatar from 'ant-design-vue/es/avatar/Avatar'
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
import AMenu from 'ant-design-vue/es/menu/index'
|
||||
|
||||
const AMenuItem = AMenu.Item
|
||||
const AMenuDivider = AMenu.Divider
|
||||
|
||||
export default {
|
||||
name: 'HeaderAvatar',
|
||||
components: {AMenu, AMenuItem, AMenuDivider, AIcon, AAvatar, ADropdown},
|
||||
computed: {
|
||||
currUser () {
|
||||
return this.$store.state.account.user
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.avatar{
|
||||
margin: 20px 4px 20px 0;
|
||||
color: #1890ff;
|
||||
background: hsla(0,0%,100%,.85);
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
19
src/layouts/MenuView.vue
Normal file
19
src/layouts/MenuView.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<global-layout>
|
||||
<transition name="page-toggle">
|
||||
<router-view />
|
||||
</transition>
|
||||
</global-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GlobalLayout from './GlobalLayout'
|
||||
export default {
|
||||
name: 'MenuView',
|
||||
components: {GlobalLayout}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
75
src/layouts/PageLayout.vue
Normal file
75
src/layouts/PageLayout.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div style="margin: -24px -24px 0px">
|
||||
<page-header :breadcrumb="breadcrumb" :title="title" :logo="logo" :avatar="avatar">
|
||||
<slot name="action" slot="action"></slot>
|
||||
<slot slot="content" name="headerContent"></slot>
|
||||
<div slot="content" v-if="!this.$slots.headerContent && desc">
|
||||
<p style="font-size: 14px;line-height: 1.5;color: rgba(0,0,0,.65)">{{desc}}</p>
|
||||
<div class="link">
|
||||
<template v-for="(link, index) in linkList">
|
||||
<a :key="index" :href="link.href"><a-icon :type="link.icon" />{{link.title}}</a>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<slot slot="extra" name="extra"></slot>
|
||||
</page-header>
|
||||
<div ref="page" :class="['page-content', layout]" >
|
||||
<slot ></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageHeader from '../components/page/PageHeader'
|
||||
import AIcon from 'ant-design-vue/es/icon/icon'
|
||||
export default {
|
||||
name: 'PageLayout',
|
||||
components: {AIcon, PageHeader},
|
||||
props: ['desc', 'logo', 'title', 'avatar', 'linkList', 'extraImage'],
|
||||
data () {
|
||||
return {
|
||||
breadcrumb: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
layout () {
|
||||
return this.$store.state.setting.layout
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
updated () {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb () {
|
||||
this.breadcrumb = this.$route.matched
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.link{
|
||||
margin-top: 16px;
|
||||
line-height: 24px;
|
||||
a{
|
||||
font-size: 14px;
|
||||
margin-right: 32px;
|
||||
i{
|
||||
font-size: 22px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.page-content{
|
||||
&.side{
|
||||
margin: 24px 24px 0px;
|
||||
}
|
||||
&.head{
|
||||
margin: 24px auto 0;
|
||||
max-width: 1400px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
55
src/layouts/PageView.vue
Normal file
55
src/layouts/PageView.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<page-layout :desc="desc" :title="title" :linkList="linkList">
|
||||
<div slot="extra" class="extraImg">
|
||||
<img :src="extraImage"/>
|
||||
</div>
|
||||
<transition name="page-toggle">
|
||||
<router-view ref="page"/>
|
||||
</transition>
|
||||
</page-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageHeader from '../components/page/PageHeader'
|
||||
import PageLayout from './PageLayout'
|
||||
export default {
|
||||
name: 'PageView',
|
||||
components: {PageLayout, PageHeader},
|
||||
data () {
|
||||
return {
|
||||
title: '',
|
||||
desc: '',
|
||||
linkList: [],
|
||||
extraImage: ''
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.getPageHeaderInfo()
|
||||
},
|
||||
updated () {
|
||||
this.getPageHeaderInfo()
|
||||
},
|
||||
methods: {
|
||||
getPageHeaderInfo () {
|
||||
this.title = this.$route.name
|
||||
const page = this.$refs.page
|
||||
if (page) {
|
||||
this.desc = page.desc
|
||||
this.linkList = page.linkList
|
||||
this.extraImage = page.extraImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.extraImg{
|
||||
margin-top: -60px;
|
||||
text-align: center;
|
||||
width: 195px;
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
src/layouts/RouteView.vue
Normal file
15
src/layouts/RouteView.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<transition name="page-toggle">
|
||||
<router-view />
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RouteView'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user