feat(projects): 主题配置抽屉: 迁移其他功能

This commit is contained in:
Soybean
2022-01-09 13:25:42 +08:00
parent 912bfdf439
commit 6d132c5977
10 changed files with 269 additions and 6 deletions

View File

@ -0,0 +1,80 @@
<template>
<n-divider title-placement="center">界面功能</n-divider>
<n-space vertical size="large">
<setting-menu label="固定头部和多页签">
<n-switch :value="theme.fixedHeaderAndTab" @update:value="setIsFixedHeaderAndTab" />
</setting-menu>
<setting-menu label="顶部菜单位置">
<n-select
class="w-120px"
size="small"
:value="theme.menu.horizontalPosition"
:options="theme.menu.horizontalPositionList"
@update:value="setHorizontalMenuPosition"
/>
</setting-menu>
<setting-menu label="头部高度">
<n-input-number
class="w-120px"
size="small"
:value="theme.header.height"
:step="1"
@update:value="handleSetNumber($event, setHeaderHeight)"
/>
</setting-menu>
<setting-menu label="多页签高度">
<n-input-number
class="w-120px"
size="small"
:value="theme.tab.height"
:step="1"
@update:value="handleSetNumber($event, setTabHeight)"
/>
</setting-menu>
<setting-menu label="多页签缓存">
<n-switch :value="theme.tab.isCache" @update:value="setTabIsCache" />
</setting-menu>
<setting-menu label="侧边栏展开宽度">
<n-input-number
class="w-120px"
size="small"
:value="theme.sider.width"
:step="10"
@update:value="handleSetNumber($event, setSiderWidth)"
/>
</setting-menu>
<setting-menu label="左侧混合侧边栏展开宽度">
<n-input-number
class="w-120px"
size="small"
:value="theme.sider.mixWidth"
:step="5"
@update:value="handleSetNumber($event, setMixSiderWidth)"
/>
</setting-menu>
</n-space>
</template>
<script lang="ts" setup>
import { NDivider, NSpace, NSwitch, NSelect, NInputNumber } from 'naive-ui';
import { useThemeStore } from '@/store';
import SettingMenu from '../SettingMenu/index.vue';
const theme = useThemeStore();
const {
setHorizontalMenuPosition,
setIsFixedHeaderAndTab,
setHeaderHeight,
setTabHeight,
setSiderWidth,
setMixSiderWidth,
setTabIsCache
} = useThemeStore();
function handleSetNumber(value: number | null, callback: (value: number) => void) {
if (value !== null) {
callback(value);
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,52 @@
<template>
<n-divider title-placement="center">界面显示</n-divider>
<n-space vertical size="large">
<setting-menu label="面包屑">
<n-switch :value="theme.header.crumb.visible" @update:value="setHeaderCrumbVisible" />
</setting-menu>
<setting-menu label="面包屑图标">
<n-switch :value="theme.header.crumb.showIcon" @update:value="setHeaderCrumbIconVisible" />
</setting-menu>
<setting-menu label="多页签">
<n-switch :value="theme.tab.visible" @update:value="setTabVisible" />
</setting-menu>
<setting-menu label="多页签风格">
<n-select
class="w-120px"
size="small"
:value="theme.tab.mode"
:options="theme.tab.modeList"
@update:value="setTabMode"
/>
</setting-menu>
<setting-menu label="页面切换动画">
<n-switch :value="theme.page.animate" @update:value="setPageIsAnimate" />
</setting-menu>
<setting-menu label="页面切换动画类型">
<n-select
class="w-120px"
size="small"
:value="theme.page.animateMode"
:options="theme.page.animateModeList"
@update:value="setPageAnimateMode"
/>
</setting-menu>
</n-space>
</template>
<script lang="ts" setup>
import { NDivider, NSpace, NSwitch, NSelect } from 'naive-ui';
import { useThemeStore } from '@/store';
import SettingMenu from '../SettingMenu/index.vue';
const theme = useThemeStore();
const {
setHeaderCrumbVisible,
setHeaderCrumbIconVisible,
setTabVisible,
setTabMode,
setPageIsAnimate,
setPageAnimateMode
} = useThemeStore();
</script>
<style scoped></style>

View File

@ -0,0 +1,16 @@
<template>
<div class="flex-y-center justify-between">
<span>{{ label }}</span>
<slot></slot>
</div>
</template>
<script lang="ts" setup>
interface Props {
/** 文本 */
label: string;
}
defineProps<Props>();
</script>
<style scoped></style>

View File

@ -0,0 +1,57 @@
<template>
<n-divider title-placement="center">主题配置</n-divider>
<n-space vertical>
<div ref="copyRef" :data-clipboard-text="dataClipboardText">
<n-button type="primary" :block="true">拷贝当前配置</n-button>
</div>
<n-button type="warning" :block="true" @click="handleResetConfig">重置当前配置</n-button>
</n-space>
</template>
<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted } from 'vue';
import { NDivider, NSpace, NButton } from 'naive-ui';
import Clipboard from 'clipboard';
import { useThemeStore } from '@/store';
const theme = useThemeStore();
const copyRef = ref<HTMLElement | null>(null);
const dataClipboardText = ref(getClipboardText());
function getClipboardText() {
return JSON.stringify(theme.$state);
}
function handleResetConfig() {
theme.resetThemeStore();
window.$message?.success('已重置配置,请重新拷贝!');
}
function clipboardEventListener() {
const copy = new Clipboard(copyRef.value!);
copy.on('success', () => {
window.$dialog?.success({
title: '操作成功',
content: '复制成功,请替换 src/settings/theme.json的内容',
positiveText: '确定'
});
});
}
const stopHandle = watch(
() => theme.$state,
() => {
dataClipboardText.value = getClipboardText();
},
{ deep: true }
);
onMounted(() => {
clipboardEventListener();
});
onUnmounted(() => {
stopHandle();
});
</script>
<style scoped></style>

View File

@ -2,5 +2,8 @@ import DrawerButton from './DrawerButton/index.vue';
import DarkMode from './DarkMode/index.vue';
import LayoutMode from './LayoutMode/index.vue';
import ThemeColorSelect from './ThemeColorSelect/index.vue';
import PageFunc from './PageFunc/index.vue';
import PageView from './PageView/index.vue';
import ThemeConfig from './ThemeConfig/index.vue';
export { DarkMode, DrawerButton, LayoutMode, ThemeColorSelect };
export { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect, PageFunc, PageView, ThemeConfig };

View File

@ -4,6 +4,9 @@
<dark-mode />
<layout-mode />
<theme-color-select />
<page-func />
<page-view />
<theme-config />
</n-drawer-content>
</n-drawer>
<drawer-button />
@ -12,7 +15,7 @@
<script setup lang="ts">
import { NDrawer, NDrawerContent } from 'naive-ui';
import { useAppStore } from '@/store';
import { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect } from './components';
import { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect, PageFunc, PageView, ThemeConfig } from './components';
const app = useAppStore();
</script>