24 整体风格配置开发 - udo-bit/naive_admin_pro GitHub Wiki
实现整体风格的配置开发
整体风格:比如我们的侧边栏布局模式和顶部布局模式,我们可以切换我们的侧边栏是正常的颜色还是反转色。 所以我们还需要实现我们的整体风格的配置和开发。
我们在layouts/setting-drawer/index.vue中,增加一个整体风格设置的配置。
<script lang="ts" setup>
const props = withDefaults(defineProps<{
floatTop?: number | string
drawerWidth?: number | string
layout?: 'side' | 'top' | 'mix'
layoutStyle?: 'light' | 'inverted'
}>(), {
floatTop: 240,
drawerWidth: 300,
})
const emit = defineEmits(['update:layout', 'update:layoutStyle'])
const onChangeStyle = (val: string) => {
emit('update:layoutStyle', val)
}
const styles = $ref([
{
id: 'light',
key: 'side',
title: '亮色风格',
},
{
id: 'inverted',
key: 'side',
inverted: true,
title: '反转色风格',
},
])
</script>
<template>
<SettingContainer title="整体风格设置">
<n-space size="large">
<template v-for="item in styles" :key="item.id">
<CheckboxLayout
:title="item.title"
:layout="item.key"
:inverted="item.inverted"
:checked="item.id === layoutStyle"
@click="onChangeStyle(item.id)"
/>
</template>
</n-space>
</SettingContainer>
</template>
接下来我们需要增加一个配置项在config/layout-theme.ts的文件中
export interface LayoutTheme {
+ layoutStyle: 'dark' | 'light' | 'inverted'
}
export const layoutThemeConfig: LayoutTheme = {
+ layoutStyle: 'light',
}
然后再base-layout中增加一个双向绑定的实现:
<template>
<SettingDrawer v-model:layout-style="layout.layoutStyle" v-model:layout="layout.layout" />
</template>
测试效果,我们发现当我们切换的时候并不会生效,这是因为我们没有在各个布局中设置,接下来我们在各个布局中配置一下反转色功能。 base-layout/index.vue
<template>
<SideLayout
v-if="layout.layout === 'side'"
v-model:collapsed="layout.collapsed"
:logo="layout.logo"
:title="layout.title"
:inverted="layout.layoutStyle === 'inverted'"
:show-sider-trigger="layout.showSiderTrigger"
:sider-width="layout.siderWidth"
:sider-collapsed-width="layout.siderCollapsedWidth"
>
<template #headerRight>
<div>
测试右侧插槽
</div>
</template>
<router-view />
</SideLayout>
<TopLayout
v-if="layout.layout === 'top'"
:logo="layout.logo"
:inverted="layout.layoutStyle === 'inverted'"
:title="layout.title"
>
<template #headerRight>
<div>
测试右侧插槽
</div>
</template>
<router-view />
</TopLayout>
</template>
由于我们的混合布局是不支持反转色的,所以在我们切换布局的同时我们要改变一下我们的整体风格的样式。 所以我们需要将我们的布局列表单独抽离出来。 在config/layout-theme中增加一个类型配置
export interface LayoutType {
key: string
id: string
inverted?: boolean
title?: string
}
然后在setting-drawer/index.vue中,删除定义写死的布局,然后改成动态传入的方式。如下(只写改动代码)
<script lang="ts" setup>
import type { LayoutType } from '~/config/layout-theme'
const props = withDefaults(defineProps<{
layoutList?: LayoutType[]
layoutStyleList?: LayoutType[]
}>(), {
})
</script>
<template>
<n-drawer v-model:show="show" :width="drawerWidth">
<n-drawer-content>
<SettingContainer v-if="layoutStyleList" title="整体风格设置">
<n-space size="large">
<template v-for="item in layoutStyleList" :key="item.id">
<CheckboxLayout
:title="item.title"
:layout="item.key"
:inverted="item.inverted"
:checked="item.id === layoutStyle"
@click="onChangeStyle(item.id)"
/>
</template>
</n-space>
</SettingContainer>
<SettingContainer v-if="layoutList" title="导航模式">
<n-space size="large">
<template v-for="item in layoutList" :key="item.key">
<CheckboxLayout :title="item.title" :layout="item.key" :checked="item.key === layout" @click="onChange(item.key)" />
</template>
</n-space>
</SettingContainer>
</n-drawer-content>
</n-drawer>
</template>
然后我们在stores/app.ts中实现根据布局自动调整布局和风格列表
import type { LayoutType } from '~/config/layout-theme'
import { layoutThemeConfig } from '~/config/layout-theme'
export const useAppStore = defineStore('app', () => {
const defaultTheme = import.meta.env.DEV ? layoutThemeConfig : useLayoutTheme()
const layout = reactive(unref(defaultTheme))
const visible = ref(false)
const toggleVisible = (val: boolean) => {
visible.value = val
}
const toggleCollapsed = (val: boolean) => {
layout.collapsed = val
}
const updateLayout = (val: 'mix' | 'side' | 'top') => {
layout.layout = val
}
const updateLayoutStyle = (val: 'light' | 'inverted') => {
layout.layoutStyle = val
}
const layoutList = computed<LayoutType[]>(() => {
return [
{
id: 'side',
key: 'side',
inverted: true,
title: 'Side Menu Layout',
},
{
id: 'top',
key: 'top',
title: 'Top Menu Layout',
},
{
id: 'mix',
key: 'mix',
title: 'Mix Menu Layout',
},
]
})
const layoutStyleList = computed<LayoutType[]>(() => {
const list: LayoutType[] = [
{
id: 'light',
key: 'side',
title: '亮色布局风格',
},
]
if (layout.layout !== 'mix') {
list.push({
id: 'inverted',
key: 'side',
inverted: true,
title: '反转色布局风格',
})
}
else {
updateLayoutStyle('light')
}
return list
})
return {
layout,
visible,
layoutList,
layoutStyleList,
toggleVisible,
toggleCollapsed,
updateLayout,
updateLayoutStyle,
}
})
然后再base-layout/index.vue中配置如下:
<script lang="ts" setup>
const { layout, visible, layoutList, layoutStyleList } = storeToRefs(appStore)
</script>
<template>
<SettingDrawer
v-model:layout-style="layout.layoutStyle"
v-model:layout="layout.layout"
:layout-list="layoutList"
:layout-style-list="layoutStyleList"
/>
</template>
测试效果