middle-admin-ant/src/layouts/PageLayout.vue

148 lines
5.0 KiB
Vue

<template>
<div class="page-layout">
<page-header ref="pageHeader" :style="`margin-top: ${multiPage ? 0 : -24}px`" :breadcrumb="breadcrumb" :title="pageTitle" :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>{{desc}}</p>
<div v-if="this.linkList" 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 v-if="this.$slots.extra" slot="extra" name="extra"></slot>
</page-header>
<div ref="page" :class="['page-content', layout, pageWidth]" >
<slot></slot>
</div>
</div>
</template>
<script>
import PageHeader from '@/components/page/header/PageHeader' // 加载头部组件
import {mapState, mapMutations} from 'vuex' // 加载vuex
import {getI18nKey} from '@/utils/routerUtil' // 加载路由工具
export default {
name: 'PageLayout', // 组件名称
components: {PageHeader}, // 注册组件
props: ['desc', 'logo', 'title', 'avatar', 'linkList', 'extraImage'], // 组件属性
data () { // 组件数据
return {
page: {}, // 页面数据
pageHeaderHeight: 0, // 页面头部高度
}
},
watch: { // 监听
$route() {
this.page = this.$route.meta.page // 监听路由变化
}
},
updated() { // 更新
if (!this._inactive) { // 如果页面不是隐藏状态
this.updatePageHeight() // 更新页面高度
}
},
activated() { // 激活
this.updatePageHeight() // 更新页面高度
},
deactivated() { // 隐藏
this.updatePageHeight(0) // 更新页面高度
},
mounted() { // 挂载
this.updatePageHeight() // 更新页面高度
},
created() { // 创建
this.page = this.$route.meta.page // 获取页面数据
},
beforeDestroy() { // 销毁前
this.updatePageHeight(0) // 更新页面高度
},
computed: {
...mapState('setting', ['layout', 'multiPage', 'pageMinHeight', 'pageWidth', 'customTitles']),
// 获取vuex数据 获取布局、多页签、页面最小高度、页面宽度、自定义标题
pageTitle() { // 页面标题
let pageTitle = this.page && this.page.title // 获取页面标题
return this.customTitle || (pageTitle && this.$t(pageTitle)) || this.title || this.routeName // 返回自定义标题、页面标题、组件标题、路由名称
},
routeName() { // 路由名称
const route = this.$route // 获取路由
return this.$t(getI18nKey(route.matched[route.matched.length - 1].path)) // 返回路由名称
},
breadcrumb() { // 面包屑
let page = this.page // 获取页面数据
let breadcrumb = page && page.breadcrumb // 获取面包屑
if (breadcrumb) { // 如果有面包屑
let i18nBreadcrumb = [] // 国际化面包屑
breadcrumb.forEach(item => { // 遍历面包屑
i18nBreadcrumb.push(this.$t(item)) // 添加国际化面包屑
})
return i18nBreadcrumb // 返回国际化面包屑
} else {
return this.getRouteBreadcrumb() // 返回路由面包屑
}
},
marginCorrect() { // 间距修正
return this.multiPage ? 24 : 0 // 返回多页签间距修正
}
},
methods: {
...mapMutations('setting', ['correctPageMinHeight']), // 获取vuex方法 更新页面最小高度
getRouteBreadcrumb() { // 获取路由面包屑
let routes = this.$route.matched // 获取路由
const path = this.$route.path // 获取路由路径
let breadcrumb = []
routes.filter(item => path.includes(item.path)) // 过滤路由
.forEach(route => { // 遍历路由
const path = route.path.length === 0 ? '/home' : route.path // 获取路由路径
breadcrumb.push(this.$t(getI18nKey(path))) // 添加国际化面包屑
})
let pageTitle = this.page && this.page.title // 获取页面标题
if (this.customTitle || pageTitle) { // 如果有自定义标题或页面标题
breadcrumb[breadcrumb.length - 1] = this.customTitle || pageTitle // 替换面包屑
}
return breadcrumb // 返回面包屑
},
/**
* 用于计算页面内容最小高度
* @param newHeight
*/
updatePageHeight(newHeight = this.$refs.pageHeader.$el.offsetHeight + this.marginCorrect) { // 更新页面高度
this.correctPageMinHeight(this.pageHeaderHeight - newHeight) // 更新页面最小高度
this.pageHeaderHeight = newHeight // 更新页面头部高度
}
}
}
</script>
<style lang="less">
.page-header{
margin: 0 -24px 0;
}
.link{
/*margin-top: 16px;*/
line-height: 24px;
a{
font-size: 14px;
margin-right: 32px;
i{
font-size: 22px;
margin-right: 8px;
}
}
}
.page-content{
position: relative;
padding: 24px 0 0;
&.side{
}
&.head.fixed{
margin: 0 auto;
max-width: 1400px;
}
}
</style>