Commit ed41e5082fd2e6109c2ad3ff77199d15ac14342a
1 parent
0362ab26
perf(setting-drawer): perf setting-drawer
Showing
16 changed files
with
801 additions
and
563 deletions
build/vite/plugin/html.ts
0 → 100644
1 | +import type { Plugin } from 'vite'; | ||
2 | +import ViteHtmlPlugin from 'vite-plugin-html'; | ||
3 | +import { isProdFn, isSiteMode, ViteEnv } from '../../utils'; | ||
4 | + | ||
5 | +import { hmScript } from '../hm'; | ||
6 | +// @ts-ignore | ||
7 | +import pkg from '../../../package.json'; | ||
8 | +import { GLOB_CONFIG_FILE_NAME } from '../../constant'; | ||
9 | + | ||
10 | +export function setupHtmlPlugin(plugins: Plugin[], env: ViteEnv) { | ||
11 | + const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env; | ||
12 | + | ||
13 | + const htmlPlugin = ViteHtmlPlugin({ | ||
14 | + // html title | ||
15 | + title: VITE_GLOB_APP_TITLE, | ||
16 | + minify: isProdFn(), | ||
17 | + options: { | ||
18 | + // Package and insert additional configuration files | ||
19 | + injectConfig: isProdFn() | ||
20 | + ? `<script src='${VITE_PUBLIC_PATH || './'}${GLOB_CONFIG_FILE_NAME}?v=${ | ||
21 | + pkg.version | ||
22 | + }-${new Date().getTime()}'></script>` | ||
23 | + : '', | ||
24 | + // Insert Baidu statistics code | ||
25 | + hmScript: isSiteMode() ? hmScript : '', | ||
26 | + title: VITE_GLOB_APP_TITLE, | ||
27 | + }, | ||
28 | + }); | ||
29 | + | ||
30 | + plugins.push(htmlPlugin); | ||
31 | + return plugins; | ||
32 | +} |
build/vite/plugin/index.ts
1 | import type { Plugin as VitePlugin } from 'vite'; | 1 | import type { Plugin as VitePlugin } from 'vite'; |
2 | import type { Plugin as rollupPlugin } from 'rollup'; | 2 | import type { Plugin as rollupPlugin } from 'rollup'; |
3 | 3 | ||
4 | -import { createMockServer } from 'vite-plugin-mock'; | ||
5 | -import { VitePWA } from 'vite-plugin-pwa'; | ||
6 | -import ViteHtmlPlugin from 'vite-plugin-html'; | ||
7 | import PurgeIcons from 'vite-plugin-purge-icons'; | 4 | import PurgeIcons from 'vite-plugin-purge-icons'; |
8 | 5 | ||
9 | import visualizer from 'rollup-plugin-visualizer'; | 6 | import visualizer from 'rollup-plugin-visualizer'; |
10 | import gzipPlugin from './gzip/index'; | 7 | import gzipPlugin from './gzip/index'; |
11 | 8 | ||
12 | -import { hmScript } from '../hm'; | ||
13 | - | ||
14 | // @ts-ignore | 9 | // @ts-ignore |
15 | import pkg from '../../../package.json'; | 10 | import pkg from '../../../package.json'; |
16 | -import { isDevFn, isProdFn, isSiteMode, ViteEnv, isReportMode, isBuildGzip } from '../../utils'; | ||
17 | -import { GLOB_CONFIG_FILE_NAME } from '../../constant'; | 11 | +import { isProdFn, isSiteMode, ViteEnv, isReportMode, isBuildGzip } from '../../utils'; |
12 | +import { setupHtmlPlugin } from './html'; | ||
13 | +import { setupPwaPlugin } from './pwa'; | ||
14 | +import { setupMockPlugin } from './mock'; | ||
18 | 15 | ||
19 | // gen vite plugins | 16 | // gen vite plugins |
20 | export function createVitePlugins(viteEnv: ViteEnv) { | 17 | export function createVitePlugins(viteEnv: ViteEnv) { |
21 | - const { VITE_USE_MOCK, VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH, VITE_USE_PWA } = viteEnv; | ||
22 | - | ||
23 | const vitePlugins: VitePlugin[] = []; | 18 | const vitePlugins: VitePlugin[] = []; |
24 | 19 | ||
25 | // vite-plugin-html | 20 | // vite-plugin-html |
26 | - vitePlugins.push( | ||
27 | - ViteHtmlPlugin({ | ||
28 | - // html title | ||
29 | - title: VITE_GLOB_APP_TITLE, | ||
30 | - minify: isProdFn(), | ||
31 | - options: { | ||
32 | - // Package and insert additional configuration files | ||
33 | - injectConfig: isProdFn() | ||
34 | - ? `<script src='${VITE_PUBLIC_PATH || './'}${GLOB_CONFIG_FILE_NAME}?v=${ | ||
35 | - pkg.version | ||
36 | - }-${new Date().getTime()}'></script>` | ||
37 | - : '', | ||
38 | - // Insert Baidu statistics code | ||
39 | - hmScript: isSiteMode() ? hmScript : '', | ||
40 | - title: VITE_GLOB_APP_TITLE, | ||
41 | - }, | ||
42 | - }) | ||
43 | - ); | 21 | + setupHtmlPlugin(vitePlugins, viteEnv); |
22 | + // vite-plugin-pwa | ||
23 | + setupPwaPlugin(vitePlugins, viteEnv); | ||
24 | + // vite-plugin-mock | ||
25 | + setupMockPlugin(vitePlugins, viteEnv); | ||
44 | 26 | ||
45 | // vite-plugin-purge-icons | 27 | // vite-plugin-purge-icons |
46 | vitePlugins.push(PurgeIcons()); | 28 | vitePlugins.push(PurgeIcons()); |
47 | 29 | ||
48 | - if (isProdFn() && VITE_USE_PWA) { | ||
49 | - vitePlugins.push( | ||
50 | - VitePWA({ | ||
51 | - manifest: { | ||
52 | - name: 'Vben Admin', | ||
53 | - short_name: 'vben_admin', | ||
54 | - icons: [ | ||
55 | - { | ||
56 | - src: './resource/img/pwa-192x192.png', | ||
57 | - sizes: '192x192', | ||
58 | - type: 'image/png', | ||
59 | - }, | ||
60 | - { | ||
61 | - src: './resource/img/pwa-512x512.png', | ||
62 | - sizes: '512x512', | ||
63 | - type: 'image/png', | ||
64 | - }, | ||
65 | - ], | ||
66 | - }, | ||
67 | - }) | ||
68 | - ); | ||
69 | - } | ||
70 | - | ||
71 | - // vite-plugin-mock | ||
72 | - if (isDevFn() && VITE_USE_MOCK) { | ||
73 | - // open mock | ||
74 | - vitePlugins.push( | ||
75 | - createMockServer({ | ||
76 | - ignore: /^\_/, | ||
77 | - mockPath: 'mock', | ||
78 | - showTime: true, | ||
79 | - }) | ||
80 | - ); | ||
81 | - } | ||
82 | return vitePlugins; | 30 | return vitePlugins; |
83 | } | 31 | } |
84 | 32 | ||
@@ -86,17 +34,15 @@ export function createVitePlugins(viteEnv: ViteEnv) { | @@ -86,17 +34,15 @@ export function createVitePlugins(viteEnv: ViteEnv) { | ||
86 | export function createRollupPlugin() { | 34 | export function createRollupPlugin() { |
87 | const rollupPlugins: rollupPlugin[] = []; | 35 | const rollupPlugins: rollupPlugin[] = []; |
88 | 36 | ||
89 | - if (isProdFn()) { | ||
90 | - if (isReportMode()) { | ||
91 | - // rollup-plugin-visualizer | ||
92 | - rollupPlugins.push( | ||
93 | - visualizer({ filename: './build/.cache/stats.html', open: true }) as Plugin | ||
94 | - ); | ||
95 | - } | ||
96 | - if (isBuildGzip() || isSiteMode()) { | ||
97 | - // rollup-plugin-gizp | ||
98 | - rollupPlugins.push(gzipPlugin()); | ||
99 | - } | 37 | + if (!isProdFn() && isReportMode()) { |
38 | + // rollup-plugin-visualizer | ||
39 | + rollupPlugins.push(visualizer({ filename: './build/.cache/stats.html', open: true }) as Plugin); | ||
100 | } | 40 | } |
41 | + | ||
42 | + if (!isProdFn() && (isBuildGzip() || isSiteMode())) { | ||
43 | + // rollup-plugin-gizp | ||
44 | + rollupPlugins.push(gzipPlugin()); | ||
45 | + } | ||
46 | + | ||
101 | return rollupPlugins; | 47 | return rollupPlugins; |
102 | } | 48 | } |
build/vite/plugin/mock.ts
0 → 100644
1 | +import { createMockServer } from 'vite-plugin-mock'; | ||
2 | +import type { Plugin } from 'vite'; | ||
3 | +import { isDevFn, ViteEnv } from '../../utils'; | ||
4 | + | ||
5 | +export function setupMockPlugin(plugins: Plugin[], env: ViteEnv) { | ||
6 | + const { VITE_USE_MOCK } = env; | ||
7 | + const mockPlugin = createMockServer({ | ||
8 | + ignore: /^\_/, | ||
9 | + mockPath: 'mock', | ||
10 | + showTime: true, | ||
11 | + }); | ||
12 | + if (isDevFn() && VITE_USE_MOCK) { | ||
13 | + plugins.push(mockPlugin); | ||
14 | + } | ||
15 | + return plugins; | ||
16 | +} |
build/vite/plugin/pwa.ts
0 → 100644
1 | +import { VitePWA } from 'vite-plugin-pwa'; | ||
2 | +import type { Plugin } from 'vite'; | ||
3 | +import { isProdFn, ViteEnv } from '../../utils'; | ||
4 | + | ||
5 | +export function setupPwaPlugin(plugins: Plugin[], env: ViteEnv) { | ||
6 | + const { VITE_USE_PWA } = env; | ||
7 | + | ||
8 | + const pwaPlugin = VitePWA({ | ||
9 | + manifest: { | ||
10 | + name: 'Vben Admin', | ||
11 | + short_name: 'vben_admin', | ||
12 | + icons: [ | ||
13 | + { | ||
14 | + src: './resource/img/pwa-192x192.png', | ||
15 | + sizes: '192x192', | ||
16 | + type: 'image/png', | ||
17 | + }, | ||
18 | + { | ||
19 | + src: './resource/img/pwa-512x512.png', | ||
20 | + sizes: '512x512', | ||
21 | + type: 'image/png', | ||
22 | + }, | ||
23 | + ], | ||
24 | + }, | ||
25 | + }); | ||
26 | + | ||
27 | + if (isProdFn() && VITE_USE_PWA) { | ||
28 | + plugins.push(pwaPlugin); | ||
29 | + } | ||
30 | + return plugins; | ||
31 | +} |
src/components/Menu/src/BasicMenu.tsx
@@ -103,7 +103,7 @@ export default defineComponent({ | @@ -103,7 +103,7 @@ export default defineComponent({ | ||
103 | const isHorizontal = unref(getIsHorizontal) || getSplit.value; | 103 | const isHorizontal = unref(getIsHorizontal) || getSplit.value; |
104 | 104 | ||
105 | return { | 105 | return { |
106 | - height: isHorizontal ? `calc(100%)` : `calc(100% - ${props.showLogo ? '48px' : '0px'})`, | 106 | + height: isHorizontal ? '100%' : `calc(100% - ${props.showLogo ? '48px' : '0px'})`, |
107 | overflowY: isHorizontal ? 'hidden' : 'auto', | 107 | overflowY: isHorizontal ? 'hidden' : 'auto', |
108 | }; | 108 | }; |
109 | } | 109 | } |
src/hooks/web/useI18n.ts
@@ -25,9 +25,9 @@ export function useI18n(namespace?: string) { | @@ -25,9 +25,9 @@ export function useI18n(namespace?: string) { | ||
25 | 25 | ||
26 | return { | 26 | return { |
27 | ...methods, | 27 | ...methods, |
28 | - t: (key: string, ...arg: Parameters<typeof t>) => { | 28 | + t: (key: string, ...arg: Partial<Parameters<typeof t>>) => { |
29 | if (!key) return ''; | 29 | if (!key) return ''; |
30 | - return t(getKey(key), ...arg); | 30 | + return t(getKey(key), ...(arg as Parameters<typeof t>)); |
31 | }, | 31 | }, |
32 | }; | 32 | }; |
33 | } | 33 | } |
src/layouts/default/setting/SettingDrawer.tsx
1 | -import type { ProjectConfig } from '/@/types/config'; | ||
2 | - | ||
3 | -import defaultSetting from '/@/settings/projectSetting'; | ||
4 | - | ||
5 | -import { defineComponent, computed, unref, FunctionalComponent } from 'vue'; | 1 | +import { defineComponent, computed, unref } from 'vue'; |
6 | import { BasicDrawer } from '/@/components/Drawer/index'; | 2 | import { BasicDrawer } from '/@/components/Drawer/index'; |
7 | -import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue'; | ||
8 | -import { Button } from '/@/components/Button'; | ||
9 | -import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue'; | 3 | +import { Divider } from 'ant-design-vue'; |
4 | +import { | ||
5 | + TypePicker, | ||
6 | + ThemePicker, | ||
7 | + SettingFooter, | ||
8 | + SwitchItem, | ||
9 | + SelectItem, | ||
10 | + InputNumberItem, | ||
11 | +} from './components'; | ||
10 | 12 | ||
11 | import { MenuTypeEnum } from '/@/enums/menuEnum'; | 13 | import { MenuTypeEnum } from '/@/enums/menuEnum'; |
12 | -import { appStore } from '/@/store/modules/app'; | ||
13 | 14 | ||
14 | -import { useMessage } from '/@/hooks/web/useMessage'; | ||
15 | -import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | ||
16 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | 15 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
17 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 16 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
18 | import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; | 17 | import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; |
@@ -20,8 +19,6 @@ import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | @@ -20,8 +19,6 @@ import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; | ||
20 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; | 19 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; |
21 | import { useI18n } from '/@/hooks/web/useI18n'; | 20 | import { useI18n } from '/@/hooks/web/useI18n'; |
22 | 21 | ||
23 | -import { updateColorWeak, updateGrayMode } from '/@/setup/theme'; | ||
24 | - | ||
25 | import { baseHandler } from './handler'; | 22 | import { baseHandler } from './handler'; |
26 | 23 | ||
27 | import { | 24 | import { |
@@ -35,146 +32,8 @@ import { | @@ -35,146 +32,8 @@ import { | ||
35 | 32 | ||
36 | import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST } from '/@/settings/colorSetting'; | 33 | import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST } from '/@/settings/colorSetting'; |
37 | 34 | ||
38 | -interface SwitchOptions { | ||
39 | - config?: DeepPartial<ProjectConfig>; | ||
40 | - def?: any; | ||
41 | - disabled?: boolean; | ||
42 | - handler?: Fn; | ||
43 | -} | ||
44 | - | ||
45 | -interface SelectConfig { | ||
46 | - options?: LabelValueOptions; | ||
47 | - def?: any; | ||
48 | - disabled?: boolean; | ||
49 | - handler?: Fn; | ||
50 | -} | ||
51 | - | ||
52 | -interface ThemePickerProps { | ||
53 | - colorList: string[]; | ||
54 | - handler: Fn; | ||
55 | - def: string; | ||
56 | -} | ||
57 | - | ||
58 | -const { createSuccessModal, createMessage } = useMessage(); | ||
59 | const { t } = useI18n(); | 35 | const { t } = useI18n(); |
60 | 36 | ||
61 | -/** | ||
62 | - * Menu type Picker comp | ||
63 | - */ | ||
64 | -const MenuTypePicker: FunctionalComponent = () => { | ||
65 | - const { getIsHorizontal, getMenuType } = useMenuSetting(); | ||
66 | - return ( | ||
67 | - <div class={`setting-drawer__siderbar`}> | ||
68 | - {menuTypeList.map((item) => { | ||
69 | - const { title, type: ItemType, mode, src } = item; | ||
70 | - return ( | ||
71 | - <Tooltip title={title} placement="bottom" key={title}> | ||
72 | - {{ | ||
73 | - default: () => ( | ||
74 | - <div | ||
75 | - onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, { | ||
76 | - mode: mode, | ||
77 | - type: ItemType, | ||
78 | - split: unref(getIsHorizontal) ? false : undefined, | ||
79 | - })} | ||
80 | - > | ||
81 | - <CheckOutlined | ||
82 | - class={['check-icon', unref(getMenuType) === ItemType ? 'active' : '']} | ||
83 | - /> | ||
84 | - <img src={src} /> | ||
85 | - </div> | ||
86 | - ), | ||
87 | - }} | ||
88 | - </Tooltip> | ||
89 | - ); | ||
90 | - })} | ||
91 | - </div> | ||
92 | - ); | ||
93 | -}; | ||
94 | - | ||
95 | -const ThemePicker: FunctionalComponent<ThemePickerProps> = (props) => { | ||
96 | - return ( | ||
97 | - <div class={`setting-drawer__theme-item`}> | ||
98 | - {props.colorList.map((color) => { | ||
99 | - return ( | ||
100 | - <span | ||
101 | - onClick={() => props.handler?.(color)} | ||
102 | - key={color} | ||
103 | - class={[props.def === color ? 'active' : '']} | ||
104 | - style={{ | ||
105 | - background: color, | ||
106 | - }} | ||
107 | - > | ||
108 | - <CheckOutlined class="icon" /> | ||
109 | - </span> | ||
110 | - ); | ||
111 | - })} | ||
112 | - </div> | ||
113 | - ); | ||
114 | -}; | ||
115 | - | ||
116 | -/** | ||
117 | - * FooterButton component | ||
118 | - */ | ||
119 | -const FooterButton: FunctionalComponent = () => { | ||
120 | - const { getRootSetting } = useRootSetting(); | ||
121 | - function handleCopy() { | ||
122 | - const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2)); | ||
123 | - unref(isSuccessRef) && | ||
124 | - createSuccessModal({ | ||
125 | - title: t('layout.setting.operatingTitle'), | ||
126 | - content: t('layout.setting.operatingContent'), | ||
127 | - }); | ||
128 | - } | ||
129 | - function handleResetSetting() { | ||
130 | - try { | ||
131 | - appStore.commitProjectConfigState(defaultSetting); | ||
132 | - const { colorWeak, grayMode } = defaultSetting; | ||
133 | - // updateTheme(themeColor); | ||
134 | - updateColorWeak(colorWeak); | ||
135 | - updateGrayMode(grayMode); | ||
136 | - createMessage.success(t('layout.setting.resetSuccess')); | ||
137 | - } catch (error) { | ||
138 | - createMessage.error(error); | ||
139 | - } | ||
140 | - } | ||
141 | - | ||
142 | - function handleClearAndRedo() { | ||
143 | - localStorage.clear(); | ||
144 | - appStore.resumeAllState(); | ||
145 | - location.reload(); | ||
146 | - } | ||
147 | - | ||
148 | - return ( | ||
149 | - <div class="setting-drawer__footer"> | ||
150 | - <Button type="primary" block onClick={handleCopy}> | ||
151 | - {() => ( | ||
152 | - <> | ||
153 | - <CopyOutlined class="mr-2" /> | ||
154 | - {t('layout.setting.copyBtn')} | ||
155 | - </> | ||
156 | - )} | ||
157 | - </Button> | ||
158 | - <Button block class="mt-2" onClick={handleResetSetting} color="warning"> | ||
159 | - {() => ( | ||
160 | - <> | ||
161 | - <RedoOutlined class="mr-2" /> | ||
162 | - {t('layout.setting.resetBtn')} | ||
163 | - </> | ||
164 | - )} | ||
165 | - </Button> | ||
166 | - <Button block class="mt-2" onClick={handleClearAndRedo} color="error"> | ||
167 | - {() => ( | ||
168 | - <> | ||
169 | - <RedoOutlined class="mr-2" /> | ||
170 | - {t('layout.setting.clearBtn')} | ||
171 | - </> | ||
172 | - )} | ||
173 | - </Button> | ||
174 | - </div> | ||
175 | - ); | ||
176 | -}; | ||
177 | - | ||
178 | export default defineComponent({ | 37 | export default defineComponent({ |
179 | name: 'SettingDrawer', | 38 | name: 'SettingDrawer', |
180 | setup(_, { attrs }) { | 39 | setup(_, { attrs }) { |
@@ -187,6 +46,7 @@ export default defineComponent({ | @@ -187,6 +46,7 @@ export default defineComponent({ | ||
187 | getFullContent, | 46 | getFullContent, |
188 | getColorWeak, | 47 | getColorWeak, |
189 | getGrayMode, | 48 | getGrayMode, |
49 | + getLockTime, | ||
190 | } = useRootSetting(); | 50 | } = useRootSetting(); |
191 | 51 | ||
192 | const { | 52 | const { |
@@ -229,38 +89,44 @@ export default defineComponent({ | @@ -229,38 +89,44 @@ export default defineComponent({ | ||
229 | function renderSidebar() { | 89 | function renderSidebar() { |
230 | return ( | 90 | return ( |
231 | <> | 91 | <> |
232 | - <MenuTypePicker /> | ||
233 | - {renderSwitchItem(t('layout.setting.splitMenu'), { | ||
234 | - handler: (e) => { | ||
235 | - baseHandler(HandlerEnum.MENU_SPLIT, e); | ||
236 | - }, | ||
237 | - def: unref(getSplit), | ||
238 | - disabled: !unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX, | ||
239 | - })} | 92 | + <TypePicker |
93 | + menuTypeList={menuTypeList} | ||
94 | + handler={(item: typeof menuTypeList[0]) => { | ||
95 | + baseHandler(HandlerEnum.CHANGE_LAYOUT, { | ||
96 | + mode: item.mode, | ||
97 | + type: item.type, | ||
98 | + split: unref(getIsHorizontal) ? false : undefined, | ||
99 | + }); | ||
100 | + }} | ||
101 | + def={unref(getMenuType)} | ||
102 | + /> | ||
103 | + <SwitchItem | ||
104 | + title={t('layout.setting.splitMenu')} | ||
105 | + event={HandlerEnum.MENU_SPLIT} | ||
106 | + def={unref(getSplit)} | ||
107 | + disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX} | ||
108 | + /> | ||
240 | </> | 109 | </> |
241 | ); | 110 | ); |
242 | } | 111 | } |
243 | 112 | ||
244 | - function renderTheme() { | 113 | + function renderHeaderTheme() { |
245 | return ( | 114 | return ( |
246 | - <> | ||
247 | - <Divider>{() => t('layout.setting.headerTheme')}</Divider> | ||
248 | - <ThemePicker | ||
249 | - colorList={HEADER_PRESET_BG_COLOR_LIST} | ||
250 | - def={unref(getHeaderBgColor)} | ||
251 | - handler={(e) => { | ||
252 | - baseHandler(HandlerEnum.HEADER_THEME, e); | ||
253 | - }} | ||
254 | - /> | ||
255 | - <Divider>{() => t('layout.setting.sidebarTheme')}</Divider> | ||
256 | - <ThemePicker | ||
257 | - colorList={SIDE_BAR_BG_COLOR_LIST} | ||
258 | - def={unref(getMenuBgColor)} | ||
259 | - handler={(e) => { | ||
260 | - baseHandler(HandlerEnum.MENU_THEME, e); | ||
261 | - }} | ||
262 | - /> | ||
263 | - </> | 115 | + <ThemePicker |
116 | + colorList={HEADER_PRESET_BG_COLOR_LIST} | ||
117 | + def={unref(getHeaderBgColor)} | ||
118 | + event={HandlerEnum.HEADER_THEME} | ||
119 | + /> | ||
120 | + ); | ||
121 | + } | ||
122 | + | ||
123 | + function renderSiderTheme() { | ||
124 | + return ( | ||
125 | + <ThemePicker | ||
126 | + colorList={SIDE_BAR_BG_COLOR_LIST} | ||
127 | + def={unref(getMenuBgColor)} | ||
128 | + event={HandlerEnum.MENU_THEME} | ||
129 | + /> | ||
264 | ); | 130 | ); |
265 | } | 131 | } |
266 | 132 | ||
@@ -268,264 +134,192 @@ export default defineComponent({ | @@ -268,264 +134,192 @@ export default defineComponent({ | ||
268 | * @description: | 134 | * @description: |
269 | */ | 135 | */ |
270 | function renderFeatures() { | 136 | function renderFeatures() { |
271 | - return [ | ||
272 | - renderSwitchItem(t('layout.setting.menuDrag'), { | ||
273 | - handler: (e) => { | ||
274 | - baseHandler(HandlerEnum.MENU_HAS_DRAG, e); | ||
275 | - }, | ||
276 | - def: unref(getCanDrag), | ||
277 | - disabled: !unref(getShowMenuRef), | ||
278 | - }), | ||
279 | - renderSwitchItem(t('layout.setting.menuSearch'), { | ||
280 | - handler: (e) => { | ||
281 | - baseHandler(HandlerEnum.HEADER_SEARCH, e); | ||
282 | - }, | ||
283 | - def: unref(getShowSearch), | ||
284 | - disabled: !unref(getShowHeader), | ||
285 | - }), | ||
286 | - renderSwitchItem(t('layout.setting.menuAccordion'), { | ||
287 | - handler: (e) => { | ||
288 | - baseHandler(HandlerEnum.MENU_ACCORDION, e); | ||
289 | - }, | ||
290 | - def: unref(getAccordion), | ||
291 | - disabled: !unref(getShowMenuRef), | ||
292 | - }), | ||
293 | - renderSwitchItem(t('layout.setting.menuCollapse'), { | ||
294 | - handler: (e) => { | ||
295 | - baseHandler(HandlerEnum.MENU_COLLAPSED, e); | ||
296 | - }, | ||
297 | - def: unref(getCollapsed), | ||
298 | - disabled: !unref(getShowMenuRef), | ||
299 | - }), | ||
300 | - renderSwitchItem(t('layout.setting.collapseMenuDisplayName'), { | ||
301 | - handler: (e) => { | ||
302 | - baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e); | ||
303 | - }, | ||
304 | - def: unref(getCollapsedShowTitle), | ||
305 | - disabled: !unref(getShowMenuRef) || !unref(getCollapsed), | ||
306 | - }), | ||
307 | - renderSwitchItem(t('layout.setting.fixedHeader'), { | ||
308 | - handler: (e) => { | ||
309 | - baseHandler(HandlerEnum.HEADER_FIXED, e); | ||
310 | - }, | ||
311 | - def: unref(getHeaderFixed), | ||
312 | - disabled: !unref(getShowHeader), | ||
313 | - }), | ||
314 | - renderSwitchItem(t('layout.setting.fixedSideBar'), { | ||
315 | - handler: (e) => { | ||
316 | - baseHandler(HandlerEnum.MENU_FIXED, e); | ||
317 | - }, | ||
318 | - def: unref(getMenuFixed), | ||
319 | - disabled: !unref(getShowMenuRef), | ||
320 | - }), | ||
321 | - renderSelectItem(t('layout.setting.topMenuLayout'), { | ||
322 | - handler: (e) => { | ||
323 | - baseHandler(HandlerEnum.MENU_TOP_ALIGN, e); | ||
324 | - }, | ||
325 | - def: unref(getTopMenuAlign), | ||
326 | - options: topMenuAlignOptions, | ||
327 | - disabled: !unref(getShowHeader) || (!unref(getIsTopMenu) && !unref(getSplit)), | ||
328 | - }), | ||
329 | - renderSelectItem(t('layout.setting.menuCollapseButton'), { | ||
330 | - handler: (e) => { | ||
331 | - baseHandler(HandlerEnum.MENU_TRIGGER, e); | ||
332 | - }, | ||
333 | - disabled: !unref(getShowMenuRef), | ||
334 | - def: unref(getTrigger), | ||
335 | - options: menuTriggerOptions, | ||
336 | - }), | ||
337 | - | ||
338 | - renderSelectItem(t('layout.setting.contentMode'), { | ||
339 | - handler: (e) => { | ||
340 | - baseHandler(HandlerEnum.CONTENT_MODE, e); | ||
341 | - }, | ||
342 | - def: unref(getContentMode), | ||
343 | - options: contentModeOptions, | ||
344 | - }), | ||
345 | - <div class={`setting-drawer__cell-item`}> | ||
346 | - <span>{t('layout.setting.autoScreenLock')}</span> | ||
347 | - <InputNumber | ||
348 | - style="width:126px" | ||
349 | - size="small" | 137 | + return ( |
138 | + <> | ||
139 | + <SwitchItem | ||
140 | + title={t('layout.setting.menuDrag')} | ||
141 | + event={HandlerEnum.MENU_HAS_DRAG} | ||
142 | + def={unref(getCanDrag)} | ||
143 | + disabled={!unref(getShowMenuRef)} | ||
144 | + /> | ||
145 | + <SwitchItem | ||
146 | + title={t('layout.setting.menuSearch')} | ||
147 | + event={HandlerEnum.HEADER_SEARCH} | ||
148 | + def={unref(getShowSearch)} | ||
149 | + disabled={!unref(getShowHeader)} | ||
150 | + /> | ||
151 | + <SwitchItem | ||
152 | + title={t('layout.setting.menuAccordion')} | ||
153 | + event={HandlerEnum.MENU_ACCORDION} | ||
154 | + def={unref(getAccordion)} | ||
155 | + disabled={!unref(getShowMenuRef)} | ||
156 | + /> | ||
157 | + <SwitchItem | ||
158 | + title={t('layout.setting.menuCollapse')} | ||
159 | + event={HandlerEnum.MENU_COLLAPSED} | ||
160 | + def={unref(getCollapsed)} | ||
161 | + disabled={!unref(getShowMenuRef)} | ||
162 | + /> | ||
163 | + <SwitchItem | ||
164 | + title={t('layout.setting.collapseMenuDisplayName')} | ||
165 | + event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE} | ||
166 | + def={unref(getCollapsedShowTitle)} | ||
167 | + disabled={!unref(getShowMenuRef) || !unref(getCollapsed)} | ||
168 | + /> | ||
169 | + <SwitchItem | ||
170 | + title={t('layout.setting.fixedHeader')} | ||
171 | + event={HandlerEnum.HEADER_FIXED} | ||
172 | + def={unref(getHeaderFixed)} | ||
173 | + disabled={!unref(getShowHeader)} | ||
174 | + /> | ||
175 | + <SwitchItem | ||
176 | + title={t('layout.setting.fixedSideBar')} | ||
177 | + event={HandlerEnum.MENU_FIXED} | ||
178 | + def={unref(getMenuFixed)} | ||
179 | + disabled={!unref(getShowMenuRef)} | ||
180 | + /> | ||
181 | + <SelectItem | ||
182 | + title={t('layout.setting.topMenuLayout')} | ||
183 | + event={HandlerEnum.MENU_TOP_ALIGN} | ||
184 | + def={unref(getTopMenuAlign)} | ||
185 | + options={topMenuAlignOptions} | ||
186 | + disabled={!unref(getShowHeader) || (!unref(getIsTopMenu) && !unref(getSplit))} | ||
187 | + /> | ||
188 | + <SelectItem | ||
189 | + title={t('layout.setting.menuCollapseButton')} | ||
190 | + event={HandlerEnum.MENU_TRIGGER} | ||
191 | + def={unref(getTrigger)} | ||
192 | + options={menuTriggerOptions} | ||
193 | + disabled={!unref(getShowMenuRef)} | ||
194 | + /> | ||
195 | + <SelectItem | ||
196 | + title={t('layout.setting.contentMode')} | ||
197 | + event={HandlerEnum.CONTENT_MODE} | ||
198 | + def={unref(getContentMode)} | ||
199 | + options={contentModeOptions} | ||
200 | + /> | ||
201 | + <InputNumberItem | ||
202 | + title={t('layout.setting.autoScreenLock')} | ||
350 | min={0} | 203 | min={0} |
351 | - onChange={(e: any) => { | ||
352 | - baseHandler(HandlerEnum.LOCK_TIME, e); | ||
353 | - }} | ||
354 | - defaultValue={appStore.getProjectConfig.lockTime} | 204 | + event={HandlerEnum.LOCK_TIME} |
205 | + defaultValue={unref(getLockTime)} | ||
355 | formatter={(value: string) => { | 206 | formatter={(value: string) => { |
356 | - if (parseInt(value) === 0) { | ||
357 | - return `0(${t('layout.setting.notAutoScreenLock')})`; | ||
358 | - } | ||
359 | - return `${value}${t('layout.setting.minute')}`; | 207 | + return parseInt(value) === 0 |
208 | + ? `0(${t('layout.setting.notAutoScreenLock')})` | ||
209 | + : `${value}${t('layout.setting.minute')}`; | ||
360 | }} | 210 | }} |
361 | /> | 211 | /> |
362 | - </div>, | ||
363 | - <div class={`setting-drawer__cell-item`}> | ||
364 | - <span>{t('layout.setting.expandedMenuWidth')}</span> | ||
365 | - <InputNumber | ||
366 | - style="width:126px" | ||
367 | - size="small" | 212 | + <InputNumberItem |
213 | + title={t('layout.setting.expandedMenuWidth')} | ||
368 | max={600} | 214 | max={600} |
369 | min={100} | 215 | min={100} |
370 | step={10} | 216 | step={10} |
217 | + event={HandlerEnum.MENU_WIDTH} | ||
371 | disabled={!unref(getShowMenuRef)} | 218 | disabled={!unref(getShowMenuRef)} |
372 | defaultValue={unref(getMenuWidth)} | 219 | defaultValue={unref(getMenuWidth)} |
373 | formatter={(value: string) => `${parseInt(value)}px`} | 220 | formatter={(value: string) => `${parseInt(value)}px`} |
374 | - onChange={(e: any) => { | ||
375 | - baseHandler(HandlerEnum.MENU_WIDTH, e); | ||
376 | - }} | ||
377 | /> | 221 | /> |
378 | - </div>, | ||
379 | - ]; | 222 | + </> |
223 | + ); | ||
380 | } | 224 | } |
381 | 225 | ||
382 | function renderContent() { | 226 | function renderContent() { |
383 | - return [ | ||
384 | - renderSwitchItem(t('layout.setting.breadcrumb'), { | ||
385 | - handler: (e) => { | ||
386 | - baseHandler(HandlerEnum.SHOW_BREADCRUMB, e); | ||
387 | - }, | ||
388 | - def: unref(getShowBreadCrumb), | ||
389 | - disabled: !unref(getShowHeader), | ||
390 | - }), | ||
391 | - renderSwitchItem(t('layout.setting.breadcrumbIcon'), { | ||
392 | - handler: (e) => { | ||
393 | - baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e); | ||
394 | - }, | ||
395 | - def: unref(getShowBreadCrumbIcon), | ||
396 | - disabled: !unref(getShowHeader), | ||
397 | - }), | ||
398 | - renderSwitchItem(t('layout.setting.tabs'), { | ||
399 | - handler: (e) => { | ||
400 | - baseHandler(HandlerEnum.TABS_SHOW, e); | ||
401 | - }, | ||
402 | - def: unref(getShowMultipleTab), | ||
403 | - }), | ||
404 | - renderSwitchItem(t('layout.setting.tabsQuickBtn'), { | ||
405 | - handler: (e) => { | ||
406 | - baseHandler(HandlerEnum.TABS_SHOW_QUICK, e); | ||
407 | - }, | ||
408 | - def: unref(getShowQuick), | ||
409 | - disabled: !unref(getShowMultipleTab), | ||
410 | - }), | ||
411 | - | ||
412 | - renderSwitchItem(t('layout.setting.sidebar'), { | ||
413 | - handler: (e) => { | ||
414 | - baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e); | ||
415 | - }, | ||
416 | - def: unref(getShowMenu), | ||
417 | - disabled: unref(getIsHorizontal), | ||
418 | - }), | ||
419 | - renderSwitchItem(t('layout.setting.header'), { | ||
420 | - handler: (e) => { | ||
421 | - baseHandler(HandlerEnum.HEADER_SHOW, e); | ||
422 | - }, | ||
423 | - def: unref(getShowHeader), | ||
424 | - }), | ||
425 | - renderSwitchItem('Logo', { | ||
426 | - handler: (e) => { | ||
427 | - baseHandler(HandlerEnum.SHOW_LOGO, e); | ||
428 | - }, | ||
429 | - def: unref(getShowLogo), | ||
430 | - }), | ||
431 | - renderSwitchItem(t('layout.setting.footer'), { | ||
432 | - handler: (e) => { | ||
433 | - baseHandler(HandlerEnum.SHOW_FOOTER, e); | ||
434 | - }, | ||
435 | - def: unref(getShowFooter), | ||
436 | - }), | ||
437 | - renderSwitchItem(t('layout.setting.fullContent'), { | ||
438 | - handler: (e) => { | ||
439 | - baseHandler(HandlerEnum.FULL_CONTENT, e); | ||
440 | - }, | ||
441 | - def: unref(getFullContent), | ||
442 | - }), | ||
443 | - renderSwitchItem(t('layout.setting.grayMode'), { | ||
444 | - handler: (e) => { | ||
445 | - baseHandler(HandlerEnum.GRAY_MODE, e); | ||
446 | - }, | ||
447 | - def: unref(getGrayMode), | ||
448 | - }), | ||
449 | - renderSwitchItem(t('layout.setting.colorWeak'), { | ||
450 | - handler: (e) => { | ||
451 | - baseHandler(HandlerEnum.COLOR_WEAK, e); | ||
452 | - }, | ||
453 | - def: unref(getColorWeak), | ||
454 | - }), | ||
455 | - ]; | ||
456 | - } | ||
457 | - | ||
458 | - function renderTransition() { | ||
459 | return ( | 227 | return ( |
460 | <> | 228 | <> |
461 | - {renderSwitchItem(t('layout.setting.progress'), { | ||
462 | - handler: (e) => { | ||
463 | - baseHandler(HandlerEnum.OPEN_PROGRESS, e); | ||
464 | - }, | ||
465 | - def: unref(getOpenNProgress), | ||
466 | - })} | ||
467 | - {renderSwitchItem(t('layout.setting.switchLoading'), { | ||
468 | - handler: (e) => { | ||
469 | - baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e); | ||
470 | - }, | ||
471 | - def: unref(getOpenPageLoading), | ||
472 | - })} | 229 | + <SwitchItem |
230 | + title={t('layout.setting.breadcrumb')} | ||
231 | + event={HandlerEnum.SHOW_BREADCRUMB} | ||
232 | + def={unref(getShowBreadCrumb)} | ||
233 | + disabled={!unref(getShowHeader)} | ||
234 | + /> | ||
235 | + | ||
236 | + <SwitchItem | ||
237 | + title={t('layout.setting.breadcrumbIcon')} | ||
238 | + event={HandlerEnum.SHOW_BREADCRUMB_ICON} | ||
239 | + def={unref(getShowBreadCrumbIcon)} | ||
240 | + disabled={!unref(getShowHeader)} | ||
241 | + /> | ||
242 | + | ||
243 | + <SwitchItem | ||
244 | + title={t('layout.setting.tabs')} | ||
245 | + event={HandlerEnum.TABS_SHOW} | ||
246 | + def={unref(getShowMultipleTab)} | ||
247 | + /> | ||
248 | + | ||
249 | + <SwitchItem | ||
250 | + title={t('layout.setting.tabsQuickBtn')} | ||
251 | + event={HandlerEnum.TABS_SHOW_QUICK} | ||
252 | + def={unref(getShowQuick)} | ||
253 | + disabled={!unref(getShowMultipleTab)} | ||
254 | + /> | ||
255 | + | ||
256 | + <SwitchItem | ||
257 | + title={t('layout.setting.sidebar')} | ||
258 | + event={HandlerEnum.MENU_SHOW_SIDEBAR} | ||
259 | + def={unref(getShowMenu)} | ||
260 | + disabled={unref(getIsHorizontal)} | ||
261 | + /> | ||
262 | + | ||
263 | + <SwitchItem | ||
264 | + title={t('layout.setting.header')} | ||
265 | + event={HandlerEnum.HEADER_SHOW} | ||
266 | + def={unref(getShowHeader)} | ||
267 | + /> | ||
268 | + <SwitchItem title="Logo" event={HandlerEnum.SHOW_LOGO} def={unref(getShowLogo)} /> | ||
269 | + <SwitchItem | ||
270 | + title={t('layout.setting.footer')} | ||
271 | + event={HandlerEnum.SHOW_FOOTER} | ||
272 | + def={unref(getShowFooter)} | ||
273 | + /> | ||
274 | + <SwitchItem | ||
275 | + title={t('layout.setting.fullContent')} | ||
276 | + event={HandlerEnum.FULL_CONTENT} | ||
277 | + def={unref(getFullContent)} | ||
278 | + /> | ||
473 | 279 | ||
474 | - {renderSwitchItem(t('layout.setting.switchAnimation'), { | ||
475 | - handler: (e) => { | ||
476 | - baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e); | ||
477 | - }, | ||
478 | - def: unref(getEnableTransition), | ||
479 | - })} | 280 | + <SwitchItem |
281 | + title={t('layout.setting.grayMode')} | ||
282 | + event={HandlerEnum.GRAY_MODE} | ||
283 | + def={unref(getGrayMode)} | ||
284 | + /> | ||
480 | 285 | ||
481 | - {renderSelectItem(t('layout.setting.animationType'), { | ||
482 | - handler: (e) => { | ||
483 | - baseHandler(HandlerEnum.ROUTER_TRANSITION, e); | ||
484 | - }, | ||
485 | - def: unref(getBasicTransition), | ||
486 | - options: routerTransitionOptions, | ||
487 | - disabled: !unref(getEnableTransition), | ||
488 | - })} | 286 | + <SwitchItem |
287 | + title={t('layout.setting.colorWeak')} | ||
288 | + event={HandlerEnum.COLOR_WEAK} | ||
289 | + def={unref(getColorWeak)} | ||
290 | + /> | ||
489 | </> | 291 | </> |
490 | ); | 292 | ); |
491 | } | 293 | } |
492 | 294 | ||
493 | - function renderSelectItem(text: string, config?: SelectConfig) { | ||
494 | - const { handler, def, disabled = false, options } = config || {}; | ||
495 | - const opt = def ? { value: def, defaultValue: def } : {}; | 295 | + function renderTransition() { |
496 | return ( | 296 | return ( |
497 | - <div class={`setting-drawer__cell-item`}> | ||
498 | - <span>{text}</span> | ||
499 | - <Select | ||
500 | - {...opt} | ||
501 | - disabled={disabled} | ||
502 | - size="small" | ||
503 | - style={{ width: '126px' }} | ||
504 | - onChange={(e) => { | ||
505 | - handler && handler(e); | ||
506 | - }} | ||
507 | - options={options} | 297 | + <> |
298 | + <SwitchItem | ||
299 | + title={t('layout.setting.progress')} | ||
300 | + event={HandlerEnum.OPEN_PROGRESS} | ||
301 | + def={unref(getOpenNProgress)} | ||
302 | + /> | ||
303 | + <SwitchItem | ||
304 | + title={t('layout.setting.switchLoading')} | ||
305 | + event={HandlerEnum.OPEN_PAGE_LOADING} | ||
306 | + def={unref(getOpenPageLoading)} | ||
508 | /> | 307 | /> |
509 | - </div> | ||
510 | - ); | ||
511 | - } | ||
512 | 308 | ||
513 | - function renderSwitchItem(text: string, options?: SwitchOptions) { | ||
514 | - const { handler, def, disabled = false } = options || {}; | ||
515 | - const opt = def ? { checked: def } : {}; | ||
516 | - return ( | ||
517 | - <div class={`setting-drawer__cell-item`}> | ||
518 | - <span>{text}</span> | ||
519 | - <Switch | ||
520 | - {...opt} | ||
521 | - disabled={disabled} | ||
522 | - onChange={(e: any) => { | ||
523 | - handler && handler(e); | ||
524 | - }} | ||
525 | - checkedChildren={t('layout.setting.on')} | ||
526 | - unCheckedChildren={t('layout.setting.off')} | 309 | + <SwitchItem |
310 | + title={t('layout.setting.switchAnimation')} | ||
311 | + event={HandlerEnum.OPEN_ROUTE_TRANSITION} | ||
312 | + def={unref(getEnableTransition)} | ||
527 | /> | 313 | /> |
528 | - </div> | 314 | + |
315 | + <SelectItem | ||
316 | + title={t('layout.setting.animationType')} | ||
317 | + event={HandlerEnum.ROUTER_TRANSITION} | ||
318 | + def={unref(getBasicTransition)} | ||
319 | + options={routerTransitionOptions} | ||
320 | + disabled={!unref(getEnableTransition)} | ||
321 | + /> | ||
322 | + </> | ||
529 | ); | 323 | ); |
530 | } | 324 | } |
531 | 325 | ||
@@ -541,7 +335,10 @@ export default defineComponent({ | @@ -541,7 +335,10 @@ export default defineComponent({ | ||
541 | <> | 335 | <> |
542 | <Divider>{() => t('layout.setting.navMode')}</Divider> | 336 | <Divider>{() => t('layout.setting.navMode')}</Divider> |
543 | {renderSidebar()} | 337 | {renderSidebar()} |
544 | - {renderTheme()} | 338 | + <Divider>{() => t('layout.setting.headerTheme')}</Divider> |
339 | + {renderHeaderTheme()} | ||
340 | + <Divider>{() => t('layout.setting.sidebarTheme')}</Divider> | ||
341 | + {renderSiderTheme()} | ||
545 | <Divider>{() => t('layout.setting.interfaceFunction')}</Divider> | 342 | <Divider>{() => t('layout.setting.interfaceFunction')}</Divider> |
546 | {renderFeatures()} | 343 | {renderFeatures()} |
547 | <Divider>{() => t('layout.setting.interfaceDisplay')}</Divider> | 344 | <Divider>{() => t('layout.setting.interfaceDisplay')}</Divider> |
@@ -549,7 +346,7 @@ export default defineComponent({ | @@ -549,7 +346,7 @@ export default defineComponent({ | ||
549 | <Divider>{() => t('layout.setting.animation')}</Divider> | 346 | <Divider>{() => t('layout.setting.animation')}</Divider> |
550 | {renderTransition()} | 347 | {renderTransition()} |
551 | <Divider /> | 348 | <Divider /> |
552 | - <FooterButton /> | 349 | + <SettingFooter /> |
553 | </> | 350 | </> |
554 | ), | 351 | ), |
555 | }} | 352 | }} |
src/layouts/default/setting/components/InputNumberItem.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <span> {{ title }}</span> | ||
4 | + <InputNumber | ||
5 | + v-bind="$attrs" | ||
6 | + size="small" | ||
7 | + :class="`${prefixCls}-input-number`" | ||
8 | + @change="handleChange" | ||
9 | + /> | ||
10 | + </div> | ||
11 | +</template> | ||
12 | +<script lang="ts"> | ||
13 | + import { defineComponent, PropType } from 'vue'; | ||
14 | + | ||
15 | + import { InputNumber } from 'ant-design-vue'; | ||
16 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
17 | + import { baseHandler } from '../handler'; | ||
18 | + import { HandlerEnum } from '../enum'; | ||
19 | + | ||
20 | + export default defineComponent({ | ||
21 | + name: 'InputNumberItem', | ||
22 | + components: { InputNumber }, | ||
23 | + props: { | ||
24 | + event: { | ||
25 | + type: Number as PropType<HandlerEnum>, | ||
26 | + default: () => {}, | ||
27 | + }, | ||
28 | + title: { | ||
29 | + type: String, | ||
30 | + }, | ||
31 | + }, | ||
32 | + setup(props) { | ||
33 | + const { prefixCls } = useDesign('setting-input-number-item'); | ||
34 | + | ||
35 | + function handleChange(e: ChangeEvent) { | ||
36 | + props.event && baseHandler(props.event, e); | ||
37 | + } | ||
38 | + return { | ||
39 | + prefixCls, | ||
40 | + handleChange, | ||
41 | + }; | ||
42 | + }, | ||
43 | + }); | ||
44 | +</script> | ||
45 | +<style lang="less" scoped> | ||
46 | + @import (reference) '../../../../design/index.less'; | ||
47 | + @prefix-cls: ~'@{namespace}-setting-input-number-item'; | ||
48 | + | ||
49 | + .@{prefix-cls} { | ||
50 | + display: flex; | ||
51 | + justify-content: space-between; | ||
52 | + margin: 16px 0; | ||
53 | + | ||
54 | + &-input-number { | ||
55 | + width: 126px; | ||
56 | + } | ||
57 | + } | ||
58 | +</style> |
src/layouts/default/setting/components/SelectItem.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <span> {{ title }}</span> | ||
4 | + <Select | ||
5 | + v-bind="getBindValue" | ||
6 | + :class="`${prefixCls}-select`" | ||
7 | + @change="handleChange" | ||
8 | + :disabled="disabled" | ||
9 | + size="small" | ||
10 | + :options="options" | ||
11 | + /> | ||
12 | + </div> | ||
13 | +</template> | ||
14 | +<script lang="ts"> | ||
15 | + import { defineComponent, PropType, computed } from 'vue'; | ||
16 | + | ||
17 | + import { Select } from 'ant-design-vue'; | ||
18 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
19 | + import { baseHandler } from '../handler'; | ||
20 | + import { HandlerEnum } from '../enum'; | ||
21 | + | ||
22 | + export default defineComponent({ | ||
23 | + name: 'SelectItem', | ||
24 | + components: { Select }, | ||
25 | + props: { | ||
26 | + event: { | ||
27 | + type: Number as PropType<HandlerEnum>, | ||
28 | + default: () => {}, | ||
29 | + }, | ||
30 | + disabled: { | ||
31 | + type: Boolean, | ||
32 | + }, | ||
33 | + title: { | ||
34 | + type: String, | ||
35 | + }, | ||
36 | + def: { | ||
37 | + type: [String, Number] as PropType<string | number>, | ||
38 | + }, | ||
39 | + initValue: { | ||
40 | + type: [String, Number] as PropType<string | number>, | ||
41 | + }, | ||
42 | + options: { | ||
43 | + type: Array as PropType<LabelValueOptions>, | ||
44 | + default: [], | ||
45 | + }, | ||
46 | + }, | ||
47 | + setup(props) { | ||
48 | + const { prefixCls } = useDesign('setting-select-item'); | ||
49 | + const getBindValue = computed(() => { | ||
50 | + return props.def ? { value: props.def, defaultValue: props.initValue || props.def } : {}; | ||
51 | + }); | ||
52 | + | ||
53 | + function handleChange(e: ChangeEvent) { | ||
54 | + props.event && baseHandler(props.event, e); | ||
55 | + } | ||
56 | + return { | ||
57 | + prefixCls, | ||
58 | + handleChange, | ||
59 | + getBindValue, | ||
60 | + }; | ||
61 | + }, | ||
62 | + }); | ||
63 | +</script> | ||
64 | +<style lang="less" scoped> | ||
65 | + @import (reference) '../../../../design/index.less'; | ||
66 | + @prefix-cls: ~'@{namespace}-setting-select-item'; | ||
67 | + | ||
68 | + .@{prefix-cls} { | ||
69 | + display: flex; | ||
70 | + justify-content: space-between; | ||
71 | + margin: 16px 0; | ||
72 | + | ||
73 | + &-select { | ||
74 | + width: 126px; | ||
75 | + } | ||
76 | + } | ||
77 | +</style> |
src/layouts/default/setting/components/SettingFooter.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <a-button type="primary" block @click="handleCopy"> | ||
4 | + <CopyOutlined class="mr-2" /> | ||
5 | + {{ t('layout.setting.copyBtn') }} | ||
6 | + </a-button> | ||
7 | + | ||
8 | + <a-button color="warning" block @click="handleResetSetting" class="my-3"> | ||
9 | + <RedoOutlined class="mr-2" /> | ||
10 | + {{ t('layout.setting.resetBtn') }} | ||
11 | + </a-button> | ||
12 | + | ||
13 | + <a-button color="error" block @click="handleClearAndRedo"> | ||
14 | + <RedoOutlined class="mr-2" /> | ||
15 | + {{ t('layout.setting.clearBtn') }} | ||
16 | + </a-button> | ||
17 | + </div> | ||
18 | +</template> | ||
19 | +<script lang="ts"> | ||
20 | + import { defineComponent, unref } from 'vue'; | ||
21 | + | ||
22 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
23 | + import { useI18n } from '/@/hooks/web/useI18n'; | ||
24 | + import { CopyOutlined, RedoOutlined } from '@ant-design/icons-vue'; | ||
25 | + import { appStore } from '/@/store/modules/app'; | ||
26 | + import defaultSetting from '/@/settings/projectSetting'; | ||
27 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
28 | + import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; | ||
29 | + import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
30 | + import { updateColorWeak, updateGrayMode } from '/@/setup/theme'; | ||
31 | + | ||
32 | + export default defineComponent({ | ||
33 | + name: 'SettingFooter', | ||
34 | + components: { CopyOutlined, RedoOutlined }, | ||
35 | + setup() { | ||
36 | + const { getRootSetting } = useRootSetting(); | ||
37 | + const { prefixCls } = useDesign('setting-footer'); | ||
38 | + const { t } = useI18n(); | ||
39 | + const { createSuccessModal, createMessage } = useMessage(); | ||
40 | + | ||
41 | + function handleCopy() { | ||
42 | + const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2)); | ||
43 | + unref(isSuccessRef) && | ||
44 | + createSuccessModal({ | ||
45 | + title: t('layout.setting.operatingTitle'), | ||
46 | + content: t('layout.setting.operatingContent'), | ||
47 | + }); | ||
48 | + } | ||
49 | + function handleResetSetting() { | ||
50 | + try { | ||
51 | + appStore.commitProjectConfigState(defaultSetting); | ||
52 | + const { colorWeak, grayMode } = defaultSetting; | ||
53 | + // updateTheme(themeColor); | ||
54 | + updateColorWeak(colorWeak); | ||
55 | + updateGrayMode(grayMode); | ||
56 | + createMessage.success(t('layout.setting.resetSuccess')); | ||
57 | + } catch (error) { | ||
58 | + createMessage.error(error); | ||
59 | + } | ||
60 | + } | ||
61 | + | ||
62 | + function handleClearAndRedo() { | ||
63 | + localStorage.clear(); | ||
64 | + appStore.resumeAllState(); | ||
65 | + location.reload(); | ||
66 | + } | ||
67 | + return { | ||
68 | + prefixCls, | ||
69 | + t, | ||
70 | + handleCopy, | ||
71 | + handleResetSetting, | ||
72 | + handleClearAndRedo, | ||
73 | + }; | ||
74 | + }, | ||
75 | + }); | ||
76 | +</script> | ||
77 | +<style lang="less" scoped> | ||
78 | + @import (reference) '../../../../design/index.less'; | ||
79 | + @prefix-cls: ~'@{namespace}-setting-footer'; | ||
80 | + | ||
81 | + .@{prefix-cls} { | ||
82 | + display: flex; | ||
83 | + flex-direction: column; | ||
84 | + align-items: center; | ||
85 | + } | ||
86 | +</style> |
src/layouts/default/setting/components/SwitchItem.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <span> {{ title }}</span> | ||
4 | + <Switch | ||
5 | + v-bind="getBindValue" | ||
6 | + @change="handleChange" | ||
7 | + :disabled="disabled" | ||
8 | + :checkedChildren="t('layout.setting.on')" | ||
9 | + :unCheckedChildren="t('layout.setting.off')" | ||
10 | + /> | ||
11 | + </div> | ||
12 | +</template> | ||
13 | +<script lang="ts"> | ||
14 | + import { defineComponent, PropType, computed } from 'vue'; | ||
15 | + | ||
16 | + import { Switch } from 'ant-design-vue'; | ||
17 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
18 | + import { useI18n } from '/@/hooks/web/useI18n'; | ||
19 | + import { baseHandler } from '../handler'; | ||
20 | + import { HandlerEnum } from '../enum'; | ||
21 | + | ||
22 | + export default defineComponent({ | ||
23 | + name: 'SwitchItem', | ||
24 | + components: { Switch }, | ||
25 | + props: { | ||
26 | + event: { | ||
27 | + type: Number as PropType<HandlerEnum>, | ||
28 | + default: () => {}, | ||
29 | + }, | ||
30 | + disabled: { | ||
31 | + type: Boolean, | ||
32 | + }, | ||
33 | + title: { | ||
34 | + type: String, | ||
35 | + }, | ||
36 | + def: { | ||
37 | + type: Boolean, | ||
38 | + }, | ||
39 | + }, | ||
40 | + setup(props) { | ||
41 | + const { prefixCls } = useDesign('setting-switch-item'); | ||
42 | + const { t } = useI18n(); | ||
43 | + | ||
44 | + const getBindValue = computed(() => { | ||
45 | + return props.def ? { checked: props.def } : {}; | ||
46 | + }); | ||
47 | + function handleChange(e: ChangeEvent) { | ||
48 | + props.event && baseHandler(props.event, e); | ||
49 | + } | ||
50 | + return { | ||
51 | + prefixCls, | ||
52 | + t, | ||
53 | + handleChange, | ||
54 | + getBindValue, | ||
55 | + }; | ||
56 | + }, | ||
57 | + }); | ||
58 | +</script> | ||
59 | +<style lang="less" scoped> | ||
60 | + @import (reference) '../../../../design/index.less'; | ||
61 | + @prefix-cls: ~'@{namespace}-setting-switch-item'; | ||
62 | + | ||
63 | + .@{prefix-cls} { | ||
64 | + display: flex; | ||
65 | + justify-content: space-between; | ||
66 | + margin: 16px 0; | ||
67 | + } | ||
68 | +</style> |
src/layouts/default/setting/components/ThemePicker.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <template v-for="color in colorList || []" :key="color"> | ||
4 | + <span | ||
5 | + @click="handleClick(color)" | ||
6 | + :class="[ | ||
7 | + `${prefixCls}__item`, | ||
8 | + { | ||
9 | + [`${prefixCls}__item--active`]: def === color, | ||
10 | + }, | ||
11 | + ]" | ||
12 | + :style="{ background: color }" | ||
13 | + > | ||
14 | + <CheckOutlined /> | ||
15 | + </span> | ||
16 | + </template> | ||
17 | + </div> | ||
18 | +</template> | ||
19 | +<script lang="ts"> | ||
20 | + import { defineComponent, PropType } from 'vue'; | ||
21 | + import { CheckOutlined } from '@ant-design/icons-vue'; | ||
22 | + | ||
23 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
24 | + | ||
25 | + import { baseHandler } from '../handler'; | ||
26 | + import { HandlerEnum } from '../enum'; | ||
27 | + | ||
28 | + export default defineComponent({ | ||
29 | + name: 'ThemePicker', | ||
30 | + components: { CheckOutlined }, | ||
31 | + props: { | ||
32 | + colorList: { | ||
33 | + type: Array as PropType<string[]>, | ||
34 | + defualt: [], | ||
35 | + }, | ||
36 | + event: { | ||
37 | + type: Number as PropType<HandlerEnum>, | ||
38 | + default: () => {}, | ||
39 | + }, | ||
40 | + def: { | ||
41 | + type: String, | ||
42 | + }, | ||
43 | + }, | ||
44 | + setup(props) { | ||
45 | + const { prefixCls } = useDesign('setting-theme-picker'); | ||
46 | + | ||
47 | + function handleClick(color: string) { | ||
48 | + props.event && baseHandler(props.event, color); | ||
49 | + } | ||
50 | + return { | ||
51 | + prefixCls, | ||
52 | + handleClick, | ||
53 | + }; | ||
54 | + }, | ||
55 | + }); | ||
56 | +</script> | ||
57 | +<style lang="less"> | ||
58 | + @import (reference) '../../../../design/index.less'; | ||
59 | + @prefix-cls: ~'@{namespace}-setting-theme-picker'; | ||
60 | + | ||
61 | + .@{prefix-cls} { | ||
62 | + display: flex; | ||
63 | + flex-wrap: wrap; | ||
64 | + margin: 16px 0; | ||
65 | + justify-content: space-around; | ||
66 | + | ||
67 | + &__item { | ||
68 | + width: 20px; | ||
69 | + height: 20px; | ||
70 | + cursor: pointer; | ||
71 | + border: 1px solid #ddd; | ||
72 | + border-radius: 2px; | ||
73 | + | ||
74 | + svg { | ||
75 | + display: none; | ||
76 | + } | ||
77 | + | ||
78 | + &--active { | ||
79 | + border: 1px solid lighten(@primary-color, 10%); | ||
80 | + | ||
81 | + svg { | ||
82 | + display: inline-block; | ||
83 | + margin: 0 0 3px 3px; | ||
84 | + font-size: 12px; | ||
85 | + fill: @white !important; | ||
86 | + } | ||
87 | + } | ||
88 | + } | ||
89 | + } | ||
90 | +</style> |
src/layouts/default/setting/components/TypePicker.vue
0 → 100644
1 | +<template> | ||
2 | + <div :class="prefixCls"> | ||
3 | + <template v-for="item in menuTypeList || []" :key="item.title"> | ||
4 | + <Tooltip :title="item.title" placement="bottom"> | ||
5 | + <div | ||
6 | + @click="handler(item)" | ||
7 | + :class="[ | ||
8 | + `${prefixCls}__item`, | ||
9 | + { | ||
10 | + [`${prefixCls}__item--active`]: def === item.type, | ||
11 | + }, | ||
12 | + ]" | ||
13 | + > | ||
14 | + <img :src="item.src" /> | ||
15 | + </div> | ||
16 | + </Tooltip> | ||
17 | + </template> | ||
18 | + </div> | ||
19 | +</template> | ||
20 | +<script lang="ts"> | ||
21 | + import { defineComponent, PropType } from 'vue'; | ||
22 | + | ||
23 | + import { Tooltip } from 'ant-design-vue'; | ||
24 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
25 | + | ||
26 | + import { menuTypeList } from '../enum'; | ||
27 | + export default defineComponent({ | ||
28 | + name: 'MenuTypePicker', | ||
29 | + components: { Tooltip }, | ||
30 | + props: { | ||
31 | + menuTypeList: { | ||
32 | + type: Array as PropType<typeof menuTypeList>, | ||
33 | + defualt: [], | ||
34 | + }, | ||
35 | + handler: { | ||
36 | + type: Function as PropType<Fn>, | ||
37 | + default: () => {}, | ||
38 | + }, | ||
39 | + def: { | ||
40 | + type: String, | ||
41 | + }, | ||
42 | + }, | ||
43 | + setup() { | ||
44 | + const { prefixCls } = useDesign('setting-menu-type-picker'); | ||
45 | + | ||
46 | + return { | ||
47 | + prefixCls, | ||
48 | + }; | ||
49 | + }, | ||
50 | + }); | ||
51 | +</script> | ||
52 | +<style lang="less" scoped> | ||
53 | + @import (reference) '../../../../design/index.less'; | ||
54 | + @prefix-cls: ~'@{namespace}-setting-menu-type-picker'; | ||
55 | + | ||
56 | + .@{prefix-cls} { | ||
57 | + display: flex; | ||
58 | + | ||
59 | + &__item { | ||
60 | + position: relative; | ||
61 | + width: 70px; | ||
62 | + height: 50px; | ||
63 | + margin: 0 20px 20px 0; | ||
64 | + cursor: pointer; | ||
65 | + border-radius: 6px; | ||
66 | + | ||
67 | + &::after { | ||
68 | + position: absolute; | ||
69 | + top: 50%; | ||
70 | + left: 50%; | ||
71 | + width: 0; | ||
72 | + height: 0; | ||
73 | + content: ''; | ||
74 | + opacity: 0; | ||
75 | + transition: all 0.3s; | ||
76 | + } | ||
77 | + | ||
78 | + &:hover, | ||
79 | + &--active { | ||
80 | + &::after { | ||
81 | + top: -8px; | ||
82 | + left: -4px; | ||
83 | + width: 80px; | ||
84 | + height: 64px; | ||
85 | + border: 2px solid @primary-color; | ||
86 | + border-radius: 6px; | ||
87 | + opacity: 1; | ||
88 | + } | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + img { | ||
93 | + width: 100%; | ||
94 | + height: 100%; | ||
95 | + cursor: pointer; | ||
96 | + } | ||
97 | + } | ||
98 | +</style> |
src/layouts/default/setting/components/index.ts
0 → 100644
1 | +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; | ||
2 | + | ||
3 | +export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue')); | ||
4 | +export const ThemePicker = createAsyncComponent(() => import('./ThemePicker.vue')); | ||
5 | +export const SettingFooter = createAsyncComponent(() => import('./SettingFooter.vue')); | ||
6 | +export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue')); | ||
7 | +export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue')); | ||
8 | +export const InputNumberItem = createAsyncComponent(() => import('./InputNumberItem.vue')); |
src/layouts/default/setting/index.less deleted
100644 → 0
1 | -.setting-drawer { | ||
2 | - .ant-drawer-body { | ||
3 | - padding-top: 0; | ||
4 | - background: @white; | ||
5 | - } | ||
6 | - | ||
7 | - &__footer { | ||
8 | - display: flex; | ||
9 | - flex-direction: column; | ||
10 | - align-items: center; | ||
11 | - } | ||
12 | - | ||
13 | - &__cell-item { | ||
14 | - display: flex; | ||
15 | - justify-content: space-between; | ||
16 | - margin: 16px 0; | ||
17 | - } | ||
18 | - | ||
19 | - &__theme-item { | ||
20 | - display: flex; | ||
21 | - flex-wrap: wrap; | ||
22 | - margin: 16px 0; | ||
23 | - justify-content: space-around; | ||
24 | - | ||
25 | - > span { | ||
26 | - width: 20px; | ||
27 | - height: 20px; | ||
28 | - cursor: pointer; | ||
29 | - border: 1px solid #ddd; | ||
30 | - border-radius: 2px; | ||
31 | - | ||
32 | - svg { | ||
33 | - display: none; | ||
34 | - } | ||
35 | - | ||
36 | - &.active { | ||
37 | - border: 1px solid lighten(@primary-color, 10%); | ||
38 | - | ||
39 | - svg { | ||
40 | - display: inline-block; | ||
41 | - margin: 0 0 3px 3px; | ||
42 | - font-size: 12px; | ||
43 | - fill: @white; | ||
44 | - } | ||
45 | - } | ||
46 | - } | ||
47 | - } | ||
48 | - | ||
49 | - &__siderbar { | ||
50 | - display: flex; | ||
51 | - | ||
52 | - > div { | ||
53 | - position: relative; | ||
54 | - | ||
55 | - .check-icon { | ||
56 | - position: absolute; | ||
57 | - top: 40%; | ||
58 | - left: 40%; | ||
59 | - display: none; | ||
60 | - color: @primary-color; | ||
61 | - | ||
62 | - &.active { | ||
63 | - display: inline-block; | ||
64 | - } | ||
65 | - } | ||
66 | - } | ||
67 | - | ||
68 | - img { | ||
69 | - margin-right: 10px; | ||
70 | - cursor: pointer; | ||
71 | - } | ||
72 | - } | ||
73 | -} |
src/layouts/default/setting/index.vue
1 | <template> | 1 | <template> |
2 | - <div @click="openDrawer" class="setting-button"> | 2 | + <div @click="openDrawer" :class="prefixCls"> |
3 | <SettingOutlined /> | 3 | <SettingOutlined /> |
4 | <SettingDrawer @register="register" /> | 4 | <SettingDrawer @register="register" /> |
5 | </div> | 5 | </div> |
@@ -10,13 +10,17 @@ | @@ -10,13 +10,17 @@ | ||
10 | import SettingDrawer from './SettingDrawer'; | 10 | import SettingDrawer from './SettingDrawer'; |
11 | 11 | ||
12 | import { useDrawer } from '/@/components/Drawer'; | 12 | import { useDrawer } from '/@/components/Drawer'; |
13 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
13 | 14 | ||
14 | export default defineComponent({ | 15 | export default defineComponent({ |
15 | name: 'SettingBtn', | 16 | name: 'SettingBtn', |
16 | components: { SettingOutlined, SettingDrawer }, | 17 | components: { SettingOutlined, SettingDrawer }, |
17 | setup() { | 18 | setup() { |
18 | const [register, { openDrawer }] = useDrawer(); | 19 | const [register, { openDrawer }] = useDrawer(); |
20 | + | ||
21 | + const { prefixCls } = useDesign('setting-button'); | ||
19 | return { | 22 | return { |
23 | + prefixCls, | ||
20 | register, | 24 | register, |
21 | openDrawer, | 25 | openDrawer, |
22 | }; | 26 | }; |
@@ -25,9 +29,9 @@ | @@ -25,9 +29,9 @@ | ||
25 | </script> | 29 | </script> |
26 | <style lang="less"> | 30 | <style lang="less"> |
27 | @import (reference) '../../../design/index.less'; | 31 | @import (reference) '../../../design/index.less'; |
28 | - @import './index.less'; | 32 | + @prefix-cls: ~'@{namespace}-setting-button'; |
29 | 33 | ||
30 | - .setting-button { | 34 | + .@{prefix-cls} { |
31 | position: absolute; | 35 | position: absolute; |
32 | top: 45%; | 36 | top: 45%; |
33 | right: 0; | 37 | right: 0; |