开发header通栏部分
接下来我们删除掉我们复制过来的样式,接下来我们来开发我们的通栏部分。
<n-layout-header inverted class="pro-admin-layout-header flex items-center px-4">
颐和园路
</n-layout-header>
<n-layout-header
inverted
class="pro-admin-layout-header flex items-center justify-between px-4"
>
<div>
左边
</div>
<div>
右边
</div>
</n-layout-header>
开发logo组件,由于我们的logo在多种布局模式是都是通用的,所以我们直接开发成一个组件,方便我们后续的复用。 在layouts目录中创建一个common的文件夹,然后创建一个logo.vue的文件,开发如下:
<script lang="ts" setup>
withDefaults(defineProps<{ src?: string;size?: number }>(), {
size: 24,
})
</script>
<template>
<n-image v-if="src" alt="logo" :height="size" :width="size" :src="src" :preview-disabled="true" />
</template>
<style scoped>
</style>
接下来标题我们也抽成一个组件进行开发,在common中创建一个title.vue的文件代码如下:
<script lang="ts" setup>
import type { CSSProperties } from 'vue'
const props = withDefaults(defineProps<{ size?: number;title?: string }>(), {
size: 20,
})
const titleStyle = computed<CSSProperties>(() => {
return {
fontSize: `${props.size}px`,
}
})
</script>
<template>
<span v-if="title" class="ml-2" :style="titleStyle">
{{ title }}
</span>
</template>
然后我们在配置默认布局中配置一个logo 在config/layout-theme.ts中添加一个logo的配置项。
import logo from '~/assets/vue.svg'
export interface LayoutTheme {
title?: string
layout: 'mix' | 'side' | 'top'
headerHeight: number
logo?: string
}
export const layoutThemeConfig: LayoutTheme = {
title: 'Naive Admin Pro',
layout: 'mix',
headerHeight: 48,
logo,
}
左侧默认固定为logo和表头,所以我们的logo和标题直接通过属性的方式传值进来控制
为了减少文档大小,只写出部分代码
<script lang="ts" setup>
import Logo from '~/layouts/common/logo.vue'
import Title from '~/layouts/common/title.vue'
const props = withDefaults(defineProps<{
headerHeight?: number
logo?: string
title?: string
}>(), {
headerHeight: 48,
})
</script>
<template>
<n-layout-header
inverted
class="pro-admin-layout-header flex items-center justify-between px-4"
>
<div class="flex items-center">
<Logo :src="logo" />
<Title :title="title" />
</div>
<div>
右边
</div>
</n-layout-header>
</template>
<style scoped>
.pro-admin-layout-header{
height: v-bind(headerHeightVar);
}
.pro-admin-layout-content{
height: v-bind(contentHeightVar);
}
</style>
右侧我们采用预留插槽的方式处理,方便我们自定义如下:
<n-layout-header
inverted
class="pro-admin-layout-header flex items-center justify-between px-4"
>
<div class="flex items-center">
<Logo :src="logo" />
<Title :title="title" />
</div>
<slot name="headerRight">
<div>右边</div>
</slot>
</n-layout-header>
我们在base-layout中测试右侧插槽是否生效:
<script lang="ts" setup>
import MixLayout from '../mix-layout/index.vue'
const appStore = useAppStore()
const { layout } = storeToRefs(appStore)
</script>
<template>
<MixLayout
v-if="layout.layout === 'mix'"
:logo="layout.logo"
:title="layout.title"
>
<template #headerRight>
<div>
测试右侧插槽
</div>
</template>
<router-view />
</MixLayout>
</template>
插槽能正常使用。