17 布局功能完善 - udo-bit/naive_admin_pro GitHub Wiki
- 侧边栏收缩功能配置
- 完善混合布局
我们先来看一下我们实现一下收缩的功能。在默认情况下,我们没有配置受控模式的侧边栏,所以整个收缩的控制是由于layout-sider自己控制的,接下来我们转换成受控模式的方式,我们在side-layout中先做属性的定义:
const props = withDefaults(defineProps<{
headerHeight?: number
logo?: string
title?: string
siderWidth?: number
siderCollapsedWidth?: number
showSiderTrigger?: boolean | 'bar' | 'arrow-circle'
inverted?: boolean
collapsed?: boolean
}>(), {
headerHeight: 48,
siderWidth: 240,
siderCollapsedWidth: 48,
inverted: false,
})
defineEmits(['update:collapsed'])
然后配置LayoutSider�
<LayoutSider
:inverted="inverted"
:collapsed-width="siderCollapsedWidth"
:collapsed="collapsed"
:width="siderWidth"
:show-trigger="showSiderTrigger"
content-style="padding: 24px;"
@update:collapsed="($event) => $emit('update:collapsed', $event)"
>
</LayoutSider>
我们在全局样式配置中也增加一个collapsed
export interface LayoutTheme {
title?: string
layout: 'mix' | 'side' | 'top'
headerHeight: number
logo?: string
siderWidth: number
siderCollapsedWidth: number
showSiderTrigger: boolean | 'bar' | 'arrow-circle'
+ collapsed: boolean
}
export const layoutThemeConfig: LayoutTheme = {
title: 'Naive Admin Pro',
layout: 'side',
headerHeight: 48,
logo,
siderWidth: 240,
siderCollapsedWidth: 48,
showSiderTrigger: 'bar',
+ collapsed: false,
}
然后我们在base-layout中使用如下:
<SideLayout
v-if="layout.layout === 'side'"
+ v-model:collapsed="layout.collapsed"
:logo="layout.logo"
:title="layout.title"
:show-sider-trigger="layout.showSiderTrigger"
:sider-width="layout.siderWidth"
:sider-collapsed-width="layout.siderCollapsedWidth"
>
<router-view />
</SideLayout>
我们来测试一下收起,发现我们的文字会被挤掉,当我们收起的时候只显示一个图标,其他的我们不需要再显示了。如下:
<Title v-if="!collapsed" :title="title" />
但是我们发现,我们收缩后图标依旧是没有了,原因是我们配置了side的padding我们直接删除掉就可以了。 删掉padding后我们的图标就不居中了,我们需要调整一下整个div的样式。 我们的图标稍微有点小,所以我们将图标的size设置的大一些,设置成30 标题的大小我们调整到22 当我们收缩的时候标题会被换行,我们在Title组件中添加truncate�类型用于当宽度不够的时候,使用省略符号配置。 最终代码如下:
<div class="flex items-center justify-center mt-24px">
<Logo :src="logo" size="30" />
<Title v-if="!collapsed" size="22" :title="title" />
</div>
我们在header中保留左右两个插槽,分别如下:
<n-layout-header
class="pro-admin-layout-header flex items-center justify-between px-4"
>
<slot name="headerLeft">
<div />
</slot>
<slot name="headerRight">
<div />
</slot>
</n-layout-header>
接下来我们在base-layout中把mix-layout中的右侧插槽放到我们的side-layout中去。
<SideLayout
v-if="layout.layout === 'side'"
v-model:collapsed="layout.collapsed"
:logo="layout.logo"
:title="layout.title"
:show-sider-trigger="layout.showSiderTrigger"
:sider-width="layout.siderWidth"
:sider-collapsed-width="layout.siderCollapsedWidth"
>
<template #headerRight>
<div>
测试右侧插槽
</div>
</template>
<router-view />
</SideLayout>
同样的,我们也需要混合布局支持collapsed�的属性,那么我们也来完善一下:
<MixLayout
v-if="layout.layout === 'mix'"
+ v-model:collapsed="layout.collapsed"
:logo="layout.logo"
:title="layout.title"
:show-sider-trigger="layout.showSiderTrigger"
:sider-width="layout.siderWidth"
:sider-collapsed-width="layout.siderCollapsedWidth"
>
...
</MixLayout>
在mix-layout/index.vue中直接拷贝side-layout中的属性
<script lang="ts" setup>
import { LayoutContent, LayoutSider, Logo, Title } from '~/layouts/common'
const props = withDefaults(defineProps<{
headerHeight?: number
logo?: string
title?: string
siderWidth?: number
siderCollapsedWidth?: number
showSiderTrigger?: boolean | 'bar' | 'arrow-circle'
+ collapsed?: boolean
}>(), {
headerHeight: 48,
siderWidth: 240,
siderCollapsedWidth: 48,
})
+ defineEmits(['update:collapsed'])
</script>
<template>
<n-layout class="h-screen">
<n-layout has-sider class="pro-admin-layout-content">
<LayoutSider
:collapsed-width="siderCollapsedWidth"
:width="siderWidth"
+ :collapsed="collapsed"
:show-trigger="showSiderTrigger"
content-style="padding: 24px;"
+ @update:collapsed="($event) => $emit('update:collapsed', $event)"
>
海淀桥
</LayoutSider>
<LayoutContent content-style="padding: 24px;">
<slot />
</LayoutContent>
</n-layout>
</n-layout>
</template>
我们切到混合布局测试