Commit 74e62cbc712bdd4d4826e5fe80f537d87e44ffce

Authored by vben
1 parent bd6b203f

feat: add useDesign

Showing 52 changed files with 260 additions and 385 deletions
.ls-lint.yml
... ... @@ -3,6 +3,7 @@ ls:
3 3 .js: kebab-case | PascalCase
4 4 .vue: PascalCase | regex:^index
5 5 .ts: camelCase | PascalCase
  6 + .tsx: camelCase | PascalCase
6 7 .d.ts: kebab-case
7 8 .mock.ts: kebab-case
8 9 .data.ts: camelCase | kebab-case
... ...
src/App.vue
... ... @@ -4,7 +4,9 @@
4 4 :locale="antConfigLocale"
5 5 :transform-cell-text="transformCellText"
6 6 >
7   - <router-view />
  7 + <AppProvider>
  8 + <router-view />
  9 + </AppProvider>
8 10 </ConfigProvider>
9 11 </template>
10 12  
... ... @@ -17,9 +19,11 @@
17 19 import { useLockPage } from '/@/hooks/web/useLockPage';
18 20 import { useLocale } from '/@/hooks/web/useLocale';
19 21  
  22 + import { AppProvider } from '/@/components/Application';
  23 +
20 24 export default defineComponent({
21 25 name: 'App',
22   - components: { ConfigProvider },
  26 + components: { ConfigProvider, AppProvider },
23 27 setup() {
24 28 // Initialize vuex internal system configuration
25 29 initAppConfigStore();
... ...
src/components/Application/index.ts
1   -import AppLocalePickerLib from './src/AppLocalePicker.vue';
2   -import AppLogoLib from './src/AppLogo.vue';
  1 +import AppLocalePicker from './src/AppLocalePicker.vue';
  2 +import AppLogo from './src/AppLogo.vue';
  3 +import AppProvider from './src/AppProvider.vue';
3 4 import { withInstall } from '../util';
4 5  
5   -export const AppLocalePicker = withInstall(AppLocalePickerLib);
6   -export const AppLogo = withInstall(AppLogoLib);
  6 +withInstall(AppLocalePicker, AppLogo, AppProvider);
  7 +
  8 +export { useAppProviderContext } from './src/useAppContext';
  9 +
  10 +export { AppLocalePicker, AppLogo, AppProvider };
... ...
src/components/Application/src/AppLocalePicker.vue
... ... @@ -69,8 +69,8 @@
69 69 });
70 70 </script>
71 71  
72   -<style lang="less">
73   - .app-locale-picker-overlay {
  72 +<style lang="less" scoped>
  73 + :global(.app-locale-picker-overlay) {
74 74 .ant-dropdown-menu-item {
75 75 min-width: 160px;
76 76 }
... ...
src/components/Application/src/AppLogo.vue
... ... @@ -4,12 +4,14 @@
4 4 -->
5 5 <template>
6 6 <div
7   - class="app-logo anticon"
8   - :class="{ theme, 'collapsed-show-title': getCollapsedShowTitle }"
  7 + class="anticon"
  8 + :class="[prefixCls, theme, { 'collapsed-show-title': getCollapsedShowTitle }]"
9 9 @click="handleGoHome"
10 10 >
11 11 <img src="/@/assets/images/logo.png" />
12   - <div class="app-logo__title ml-2 ellipsis" v-show="showTitle">{{ globSetting.title }}</div>
  12 + <div class="ml-2 ellipsis" :class="[`${prefixCls}__title`]" v-show="showTitle">
  13 + {{ globSetting.title }}
  14 + </div>
13 15 </div>
14 16 </template>
15 17 <script lang="ts">
... ... @@ -23,6 +25,8 @@
23 25  
24 26 import { propTypes } from '/@/utils/propTypes';
25 27  
  28 + import { useDesign } from '/@/hooks/web/useDesign';
  29 +
26 30 export default defineComponent({
27 31 name: 'AppLogo',
28 32 props: {
... ... @@ -34,6 +38,8 @@
34 38 showTitle: propTypes.bool.def(true),
35 39 },
36 40 setup() {
  41 + const { prefixCls } = useDesign('app-logo');
  42 +
37 43 const { getCollapsedShowTitle } = useMenuSetting();
38 44  
39 45 const globSetting = useGlobSetting();
... ... @@ -48,17 +54,19 @@
48 54 handleGoHome,
49 55 globSetting,
50 56 getCollapsedShowTitle,
  57 + prefixCls,
51 58 };
52 59 },
53 60 });
54 61 </script>
55 62 <style lang="less" scoped>
56 63 @import (reference) '../../../design/index.less';
  64 + @prefix-cls: ~'@{namespace}-app-logo';
57 65  
58   - .app-logo {
  66 + .@{prefix-cls} {
59 67 display: flex;
60 68 align-items: center;
61   - padding-left: 10px;
  69 + padding-left: 12px;
62 70 cursor: pointer;
63 71  
64 72 &.collapsed-show-title {
... ...
src/components/Application/src/AppProvider.vue 0 → 100644
  1 +<template>
  2 + <slot />
  3 +</template>
  4 +<script lang="ts">
  5 + import type { PropType } from 'vue';
  6 + import { defineComponent, toRefs } from 'vue';
  7 +
  8 + import { createAppProviderContext } from './useAppContext';
  9 + export default defineComponent({
  10 + name: 'AppProvider',
  11 + inheritAttrs: false,
  12 + props: {
  13 + prefixCls: {
  14 + type: String as PropType<string>,
  15 + default: 'vben',
  16 + },
  17 + },
  18 + setup(props) {
  19 + const { prefixCls } = toRefs(props);
  20 + createAppProviderContext({ prefixCls });
  21 + return {};
  22 + },
  23 + });
  24 +</script>
... ...
src/components/Application/src/useAppContext.ts 0 → 100644
  1 +import { InjectionKey, Ref } from 'vue';
  2 +import { createContext, useContext } from '/@/hooks/core/useContext';
  3 +
  4 +export interface AppProviderContextProps {
  5 + prefixCls: Ref<string>;
  6 +}
  7 +
  8 +const key: InjectionKey<AppProviderContextProps> = Symbol();
  9 +
  10 +export function createAppProviderContext(context: AppProviderContextProps) {
  11 + return createContext<AppProviderContextProps>(context, key);
  12 +}
  13 +
  14 +export function useAppProviderContext() {
  15 + return useContext<AppProviderContextProps>(key);
  16 +}
... ...
src/components/Authority/index.ts
1   -import AuthorityLib from './src/index.vue';
  1 +import Authority from './src/index.vue';
2 2  
3 3 import { withInstall } from '../util';
4 4  
5   -export const Authority = withInstall(AuthorityLib);
  5 +withInstall(Authority);
  6 +
  7 +export { Authority };
... ...
src/components/Basic/index.ts
1   -import BasicArrowLib from './src/BasicArrow.vue';
2   -import BasicHelpLib from './src/BasicHelp.vue';
3   -import BasicTitleLib from './src/BasicTitle.vue';
  1 +import BasicArrow from './src/BasicArrow.vue';
  2 +import BasicHelp from './src/BasicHelp.vue';
  3 +import BasicTitle from './src/BasicTitle.vue';
4 4  
5 5 import { withInstall } from '../util';
6 6  
7   -export const BasicArrow = withInstall(BasicArrowLib);
8   -export const BasicHelp = withInstall(BasicHelpLib);
9   -export const BasicTitle = withInstall(BasicTitleLib);
  7 +withInstall(BasicArrow, BasicHelp, BasicTitle);
  8 +
  9 +export { BasicArrow, BasicHelp, BasicTitle };
... ...
src/components/Button/index.ts
1   -import ButtonLib from './src/BasicButton.vue';
  1 +import Button from './src/BasicButton.vue';
2 2 import { withInstall } from '../util';
3 3  
4   -export const Button = withInstall(ButtonLib);
  4 +withInstall(Button);
  5 +
  6 +export { Button };
... ...
src/components/ClickOutSide/index.ts
1   -import ClickOutSideLib from './src/index.vue';
  1 +import ClickOutSide from './src/index.vue';
2 2 import { withInstall } from '../util';
3 3  
4   -export const ClickOutSide = withInstall(ClickOutSideLib);
  4 +withInstall(ClickOutSide);
  5 +
  6 +export { ClickOutSide };
... ...
src/components/Container/index.ts
1   -import ScrollContainerLib from './src/ScrollContainer.vue';
2   -import CollapseContainerLib from './src/collapse/CollapseContainer.vue';
3   -import LazyContainerLib from './src/LazyContainer.vue';
  1 +import ScrollContainer from './src/ScrollContainer.vue';
  2 +import CollapseContainer from './src/collapse/CollapseContainer.vue';
  3 +import LazyContainer from './src/LazyContainer.vue';
4 4 import { withInstall } from '../util';
5 5  
  6 +withInstall(ScrollContainer, CollapseContainer, LazyContainer);
  7 +
6 8 export * from './src/types';
7 9  
8   -export const ScrollContainer = withInstall(ScrollContainerLib);
9   -export const CollapseContainer = withInstall(CollapseContainerLib);
10   -export const LazyContainer = withInstall(LazyContainerLib);
  10 +export { ScrollContainer, CollapseContainer, LazyContainer };
... ...
src/components/CountTo/index.ts
1 1 // Transform vue-count-to to support vue3 version
2 2  
3   -import CountToLib from './src/index.vue';
  3 +import CountTo from './src/index.vue';
4 4 import { withInstall } from '../util';
5 5  
6   -export const CountTo = withInstall(CountToLib);
  6 +withInstall(CountTo);
  7 +export { CountTo };
... ...
src/components/Description/index.ts
1   -import DescriptionLib from './src/index';
  1 +import Description from './src/index';
2 2  
3 3 import { withInstall } from '../util';
4 4  
  5 +withInstall(Description);
  6 +
5 7 export * from './src/types';
6 8 export { useDescription } from './src/useDescription';
7   -
8   -export const Description = withInstall(DescriptionLib);
  9 +export { Description };
... ...
src/components/Drawer/index.ts
1   -import BasicDrawerLib from './src/BasicDrawer';
  1 +import BasicDrawer from './src/BasicDrawer';
2 2 import { withInstall } from '../util';
3 3  
  4 +withInstall(BasicDrawer);
4 5 export * from './src/types';
5 6 export { useDrawer, useDrawerInner } from './src/useDrawer';
6   -export const BasicDrawer = withInstall(BasicDrawerLib);
  7 +export { BasicDrawer };
... ...
src/components/Dropdown/index.ts
1   -import DropdownLib from './src/Dropdown';
  1 +import Dropdown from './src/Dropdown';
2 2 import { withInstall } from '../util';
3 3  
  4 +withInstall(Dropdown);
4 5 export * from './src/types';
5 6  
6   -export const Dropdown = withInstall(DropdownLib);
  7 +export { Dropdown };
... ...
src/components/Excel/index.ts
1   -import ImportExcelLib from './src/ImportExcel.vue';
2   -import ExportExcelModelLib from './src/ExportExcelModel.vue';
  1 +import ImportExcel from './src/ImportExcel.vue';
  2 +import ExportExcelModel from './src/ExportExcelModel.vue';
3 3  
4 4 import { withInstall } from '../util';
5 5  
  6 +withInstall(ImportExcel, ExportExcelModel);
  7 +
6 8 export * from './src/types';
7 9  
8 10 export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';
9 11  
10   -export const ImportExcel = withInstall(ImportExcelLib);
11   -export const ExportExcelModel = withInstall(ExportExcelModelLib);
  12 +export { ImportExcel, ExportExcelModel };
... ...
src/components/Form/index.ts
1   -import BasicFormLib from './src/BasicForm.vue';
  1 +import BasicForm from './src/BasicForm.vue';
2 2 import { withInstall } from '../util';
3 3  
  4 +withInstall(BasicForm);
  5 +
4 6 export * from './src/types/form';
5 7 export * from './src/types/formItem';
6 8  
7 9 export { useComponentRegister } from './src/hooks/useComponentRegister';
8 10 export { useForm } from './src/hooks/useForm';
9 11  
10   -export const BasicForm = withInstall(BasicFormLib);
  12 +export { BasicForm };
... ...
src/components/Loading/index.ts
1 1 import './src/indicator';
2   -import LoadingLib from './src/index.vue';
  2 +import Loading from './src/index.vue';
3 3 import { withInstall } from '../util';
4 4  
  5 +withInstall(Loading);
5 6 export { useLoading } from './src/useLoading';
6 7 export { createLoading } from './src/createLoading';
7 8  
8   -export const Loading = withInstall(LoadingLib);
  9 +export { Loading };
... ...
src/components/Markdown/index.ts
1   -import MarkDownLib from './src/index.vue';
  1 +import MarkDown from './src/index.vue';
2 2  
3 3 import { withInstall } from '../util';
4 4  
  5 +withInstall(MarkDown);
  6 +
5 7 export * from './src/types';
6 8  
7   -export const MarkDown = withInstall(MarkDownLib);
  9 +export { MarkDown };
... ...
src/components/Menu/index.ts
1   -import BasicMenuLib from './src/BasicMenu';
  1 +import BasicMenu from './src/BasicMenu';
2 2 import { withInstall } from '../util';
3 3  
4   -export const BasicMenu = withInstall(BasicMenuLib);
  4 +withInstall(BasicMenu);
  5 +export { BasicMenu };
... ...
src/components/Menu/src/BasicMenu.tsx
... ... @@ -15,7 +15,6 @@ import {
15 15 ComputedRef,
16 16 } from 'vue';
17 17 import { Menu } from 'ant-design-vue';
18   -import SearchInput from './SearchInput.vue';
19 18 import MenuContent from './MenuContent';
20 19 // import { ScrollContainer } from '/@/components/Container';
21 20  
... ... @@ -24,8 +23,7 @@ import { ThemeEnum } from &#39;/@/enums/appEnum&#39;;
24 23  
25 24 import { appStore } from '/@/store/modules/app';
26 25  
27   -import { useSearchInput } from './hooks/useSearchInput';
28   -import { useOpenKeys } from './hooks/useOpenKeys';
  26 +import { useOpenKeys } from './useOpenKeys';
29 27 import { useRouter } from 'vue-router';
30 28  
31 29 import { isFunction } from '/@/utils/is';
... ... @@ -43,51 +41,39 @@ export default defineComponent({
43 41 emits: ['menuClick'],
44 42 setup(props, { slots, emit }) {
45 43 const currentParentPath = ref('');
  44 +
46 45 const menuState = reactive<MenuState>({
47 46 defaultSelectedKeys: [],
48 47 mode: props.mode,
49 48 theme: computed(() => props.theme) as ComputedRef<ThemeEnum>,
50 49 openKeys: [],
51   - searchValue: '',
52 50 selectedKeys: [],
53 51 collapsedOpenKeys: [],
54 52 });
55 53  
56 54 const { getCollapsed } = useMenuSetting();
57   - const { currentRoute } = useRouter();
58 55  
59   - const { items, flatItems, isAppMenu, mode, accordion } = toRefs(props);
  56 + const { currentRoute } = useRouter();
60 57  
61   - const { handleInputChange, handleInputClick } = useSearchInput({
62   - flatMenusRef: flatItems,
63   - emit: emit,
64   - menuState,
65   - handleMenuChange,
66   - });
  58 + const { items, flatItems, mode, accordion } = toRefs(props);
67 59  
68 60 const { handleOpenChange, resetKeys, setOpenKeys } = useOpenKeys(
69 61 menuState,
70 62 items,
71 63 flatItems,
72   - isAppMenu,
73 64 mode,
74 65 accordion
75 66 );
76 67  
77 68 const getOpenKeys = computed(() => {
78   - if (props.isAppMenu) {
79   - return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
80   - }
81   - return menuState.openKeys;
  69 + return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
82 70 });
83 71  
84 72 // menu外层样式
85 73 const getMenuWrapStyle = computed((): any => {
86   - const { showLogo, search } = props;
  74 + const { showLogo } = props;
87 75 let offset = 0;
88   - if (search) {
89   - offset += 54;
90   - }
  76 +
91 77 if (showLogo) {
92 78 offset += 46;
93 79 }
... ... @@ -110,7 +96,7 @@ export default defineComponent({
110 96 cls.push('basic-menu__sidebar-hor');
111 97 }
112 98  
113   - if (!props.isHorizontal && props.isAppMenu && appStore.getProjectConfig.menuSetting.split) {
  99 + if (!props.isHorizontal && appStore.getProjectConfig.menuSetting.split) {
114 100 cls.push('basic-menu__second');
115 101 }
116 102 return cls;
... ... @@ -197,7 +183,6 @@ export default defineComponent({
197 183 level={index}
198 184 isHorizontal={props.isHorizontal}
199 185 showTitle={unref(showTitle)}
200   - searchValue={menuState.searchValue}
201 186 />,
202 187 ]}
203 188 </Menu.Item>
... ... @@ -212,7 +197,6 @@ export default defineComponent({
212 197 item={menu}
213 198 level={index}
214 199 isHorizontal={props.isHorizontal}
215   - searchValue={menuState.searchValue}
216 200 />,
217 201 ],
218 202 default: () => renderMenuItem(menu.children, index + 1),
... ... @@ -227,11 +211,9 @@ export default defineComponent({
227 211 const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState;
228 212  
229 213 const inlineCollapsedObj = isInline
230   - ? props.isAppMenu
231   - ? {
232   - inlineCollapsed: unref(getCollapsed),
233   - }
234   - : { inlineCollapsed: props.inlineCollapsed }
  214 + ? {
  215 + inlineCollapsed: unref(getCollapsed),
  216 + }
235 217 : {};
236 218 return (
237 219 <Menu
... ... @@ -267,17 +249,8 @@ export default defineComponent({
267 249 ) : (
268 250 <section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}>
269 251 {getSlot(slots, 'header')}
270   - <SearchInput
271   - class={!props.search ? 'hidden' : ''}
272   - theme={props.theme as ThemeEnum}
273   - onChange={handleInputChange}
274   - onClick={handleInputClick}
275   - collapsed={unref(getCollapsed)}
276   - />
277 252  
278   - {/* <section style={unref(getMenuWrapStyle)}> */}
279 253 <section style={unref(getMenuWrapStyle)} class="basic-menu__content">
280   - {/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
281 254 {renderMenu()}
282 255 </section>
283 256 </section>
... ...
src/components/Menu/src/BasicMenu.vue 0 → 100644
  1 +<template>
  2 + <div> </div>
  3 +</template>
  4 +<script lang="ts">
  5 + import { defineComponent } from 'vue';
  6 + export default defineComponent({
  7 + setup() {
  8 + return {};
  9 + },
  10 + });
  11 +</script>
... ...
src/components/Menu/src/MenuContent.tsx
... ... @@ -8,11 +8,6 @@ import { useI18n } from &#39;/@/hooks/web/useI18n&#39;;
8 8 export default defineComponent({
9 9 name: 'MenuContent',
10 10 props: {
11   - searchValue: {
12   - type: String as PropType<string>,
13   - default: '',
14   - },
15   -
16 11 item: {
17 12 type: Object as PropType<MenuType>,
18 13 default: null,
... ... @@ -35,11 +30,7 @@ export default defineComponent({
35 30 setup(props) {
36 31 const { t } = useI18n();
37 32  
38   - const getI18nName = computed(() => {
39   - const { name } = props.item;
40   -
41   - return t(name);
42   - });
  33 + const getI18nName = computed(() => t(props.item?.name));
43 34 /**
44 35 * @description: 渲染图标
45 36 */
... ... @@ -71,28 +62,18 @@ export default defineComponent({
71 62 const { showTitle } = props;
72 63 const { icon } = props.item;
73 64 const name = unref(getI18nName);
74   - const searchValue = props.searchValue || '';
75   - const index = name.indexOf(searchValue);
76 65  
77   - const beforeStr = name.substr(0, index);
78   - const afterStr = name.substr(index + searchValue.length);
79 66 const cls = showTitle ? ['show-title'] : ['basic-menu__name'];
80 67  
81 68 return (
82 69 <>
83 70 {renderIcon(icon!)}
84   - {index > -1 && searchValue ? (
85   - <span class={cls}>
86   - {beforeStr}
87   - <span class={`basic-menu__keyword`}>{searchValue}</span>
88   - {afterStr}
89   - </span>
90   - ) : (
  71 + {
91 72 <span class={[cls]}>
92 73 {name}
93 74 {renderTag()}
94 75 </span>
95   - )}
  76 + }
96 77 </>
97 78 );
98 79 };
... ...
src/components/Menu/src/SearchInput.vue deleted 100644 → 0
1   -<template>
2   - <section class="menu-search-input" @Click="handleClick" :class="searchClass">
3   - <a-input-search
4   - :placeholder="t('component.menu.search')"
5   - class="menu-search-input__search"
6   - allowClear
7   - @change="handleChange"
8   - />
9   - </section>
10   -</template>
11   -<script lang="ts">
12   - import type { PropType } from 'vue';
13   - import { defineComponent, computed } from 'vue';
14   - import { ThemeEnum } from '/@/enums/appEnum';
15   - // hook
16   - import { useDebounce } from '/@/hooks/core/useDebounce';
17   - import { useI18n } from '/@/hooks/web/useI18n';
18   - //
19   - export default defineComponent({
20   - name: 'BasicMenuSearchInput',
21   - props: {
22   - // Whether to expand, used in the left menu
23   - collapsed: {
24   - type: Boolean as PropType<boolean>,
25   - default: true,
26   - },
27   - theme: {
28   - type: String as PropType<ThemeEnum>,
29   - },
30   - },
31   - setup(props, { emit }) {
32   - const { t } = useI18n();
33   -
34   - const [debounceEmitChange] = useDebounce(emitChange, 200);
35   -
36   - function emitChange(value?: string): void {
37   - emit('change', value);
38   - }
39   -
40   - function handleChange(e: ChangeEvent): void {
41   - const { collapsed } = props;
42   - if (collapsed) return;
43   - debounceEmitChange(e.target.value);
44   - }
45   -
46   - function handleClick(): void {
47   - emit('click');
48   - }
49   -
50   - const searchClass = computed(() => {
51   - const cls: string[] = [];
52   - cls.push(props.theme ? `menu-search-input__search--${props.theme}` : '');
53   - cls.push(props.collapsed ? 'hide-search-icon' : '');
54   - return cls;
55   - });
56   -
57   - return { handleClick, searchClass, handleChange, t };
58   - },
59   - });
60   -</script>
61   -<style lang="less">
62   - @import (reference) '../../../design/index.less';
63   - // 输入框背景颜色 深
64   - @input-dark-bg-color: #516085;
65   -
66   - @icon-color: #c0c4cc;
67   -
68   - .menu-search-input {
69   - margin: 12px 8px;
70   -
71   - &.hide-search-icon {
72   - .ant-input,
73   - .ant-input-suffix {
74   - opacity: 0;
75   - transition: all 0.5s;
76   - }
77   - }
78   -
79   - &__search--dark {
80   - .ant-input-affix-wrapper,
81   - .ant-input {
82   - .set-bg();
83   - }
84   -
85   - .ant-input-search-icon,
86   - .ant-input-clear-icon {
87   - color: rgba(255, 255, 255, 0.4) !important;
88   - }
89   - }
90   -
91   - &__search--light {
92   - .ant-input-affix-wrapper,
93   - .ant-input {
94   - color: @text-color-base;
95   - background: #fff;
96   - outline: none;
97   - }
98   -
99   - .ant-input-search-icon {
100   - color: @icon-color;
101   - }
102   - }
103   - }
104   -
105   - .set-bg() {
106   - color: #fff;
107   - background: @sider-dark-lighten-1-bg-color;
108   - border: 0;
109   - outline: none;
110   - }
111   - .hide-outline() {
112   - border: none;
113   - outline: none;
114   - box-shadow: none;
115   - }
116   -</style>
src/components/Menu/src/hooks/useSearchInput.ts deleted 100644 → 0
1   -import type { Menu as MenuType } from '/@/router/types';
2   -import type { MenuState } from '../types';
3   -import type { Ref } from 'vue';
4   -
5   -import { isString } from '/@/utils/is';
6   -import { unref } from 'vue';
7   -import { es6Unique } from '/@/utils';
8   -import { getAllParentPath } from '/@/router/helper/menuHelper';
9   -
10   -interface UseSearchInputOptions {
11   - menuState: MenuState;
12   - flatMenusRef: Ref<MenuType[]>;
13   - emit: EmitType;
14   - handleMenuChange: Fn;
15   -}
16   -export function useSearchInput({
17   - menuState,
18   - flatMenusRef,
19   - handleMenuChange,
20   - emit,
21   -}: UseSearchInputOptions) {
22   - /**
23   - * @description: 输入框搜索
24   - */
25   - function handleInputChange(value?: string): void {
26   - if (!isString(value)) {
27   - value = (value as any).target.value;
28   - }
29   - if (!value) {
30   - handleMenuChange && handleMenuChange();
31   - }
32   -
33   - menuState.searchValue = value || '';
34   - if (!value) {
35   - menuState.openKeys = [];
36   - return;
37   - }
38   -
39   - const flatMenus = unref(flatMenusRef);
40   - let openKeys: string[] = [];
41   - for (const menu of flatMenus) {
42   - const { name, path } = menu;
43   - if (!name.includes(value)) {
44   - continue;
45   - }
46   - openKeys = openKeys.concat(getAllParentPath(flatMenus, path));
47   - }
48   - openKeys = es6Unique(openKeys);
49   - menuState.openKeys = openKeys;
50   - }
51   -
52   - // 搜索框点击
53   - function handleInputClick(e: any): void {
54   - emit('clickSearchInput', e);
55   - }
56   -
57   - return { handleInputChange, handleInputClick };
58   -}
src/components/Menu/src/props.ts
... ... @@ -20,11 +20,7 @@ export const basicProps = {
20 20 type: Boolean as PropType<boolean>,
21 21 default: false,
22 22 },
23   - // 是否显示搜索框
24   - search: {
25   - type: Boolean as PropType<boolean>,
26   - default: true,
27   - },
  23 +
28 24 // 最好是4 倍数
29 25 inlineIndent: {
30 26 type: Number as PropType<number>,
... ... @@ -51,10 +47,7 @@ export const basicProps = {
51 47 type: Boolean as PropType<boolean>,
52 48 default: false,
53 49 },
54   - isAppMenu: {
55   - type: Boolean as PropType<boolean>,
56   - default: true,
57   - },
  50 +
58 51 isHorizontal: {
59 52 type: Boolean as PropType<boolean>,
60 53 default: false,
... ...
src/components/Menu/src/types.ts
... ... @@ -17,9 +17,6 @@ export interface MenuState {
17 17 // 展开数组
18 18 openKeys: string[];
19 19  
20   - // 搜索值
21   - searchValue: string;
22   -
23 20 // 当前选中的菜单项 key 数组
24 21 selectedKeys: string[];
25 22  
... ...
src/components/Menu/src/hooks/useOpenKeys.ts renamed to src/components/Menu/src/useOpenKeys.ts
1 1 import { MenuModeEnum } from '/@/enums/menuEnum';
2 2 import type { Menu as MenuType } from '/@/router/types';
3   -import type { MenuState } from '../types';
  3 +import type { MenuState } from './types';
4 4 import type { Ref } from 'vue';
5 5  
6 6 import { unref } from 'vue';
... ... @@ -12,14 +12,11 @@ export function useOpenKeys(
12 12 menuState: MenuState,
13 13 menus: Ref<MenuType[]>,
14 14 flatMenusRef: Ref<MenuType[]>,
15   - isAppMenu: Ref<boolean>,
16 15 mode: Ref<MenuModeEnum>,
17 16 accordion: Ref<boolean>
18 17 ) {
19 18 const { getCollapsed } = useMenuSetting();
20   - /**
21   - * @description:设置展开
22   - */
  19 +
23 20 function setOpenKeys(menu: MenuType) {
24 21 const flatMenus = unref(flatMenusRef);
25 22 if (!unref(accordion)) {
... ... @@ -50,7 +47,7 @@ export function useOpenKeys(
50 47 rootSubMenuKeys.push(path);
51 48 }
52 49 }
53   - if (!unref(getCollapsed) || !unref(isAppMenu)) {
  50 + if (!unref(getCollapsed)) {
54 51 const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1);
55 52 if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) {
56 53 menuState.openKeys = openKeys;
... ...
src/components/Modal/index.ts
1 1 import './src/index.less';
2   -import BasicModalLib from './src/BasicModal';
  2 +import BasicModal from './src/BasicModal';
3 3 import { withInstall } from '../util';
4 4  
  5 +withInstall(BasicModal);
  6 +
5 7 export { useModalContext } from './src/useModalContext';
6 8 export { useModal, useModalInner } from './src/useModal';
7 9 export * from './src/types';
8   -export const BasicModal = withInstall(BasicModalLib);
  10 +export { BasicModal };
... ...
src/components/Page/index.ts
1   -import PageFooterLib from './src/PageFooter.vue';
  1 +import PageFooter from './src/PageFooter.vue';
2 2 import { withInstall } from '../util';
3 3  
4   -export const PageFooter = withInstall(PageFooterLib);
  4 +withInstall(PageFooter);
  5 +export { PageFooter };
... ...
src/components/StrengthMeter/index.tsx
1   -import StrengthMeterLib from './src/index';
  1 +import StrengthMeter from './src/index';
2 2 import { withInstall } from '../util';
3 3  
4   -export const StrengthMeter = withInstall(StrengthMeterLib);
  4 +withInstall(StrengthMeter);
  5 +export { StrengthMeter };
... ...
src/components/Tinymce/index.ts
1   -import TinymceLib from './src/Editor.vue';
  1 +import Tinymce from './src/Editor.vue';
2 2 import { withInstall } from '../util';
3 3  
4   -export const Tinymce = withInstall(TinymceLib);
  4 +withInstall(Tinymce);
  5 +export { Tinymce };
... ...
src/components/Upload/index.ts
1   -import type { App } from 'vue';
2 1 import BasicUpload from './src/BasicUpload.vue';
  2 +import { withInstall } from '../util';
3 3  
4   -export default (app: App): void => {
5   - app.component(BasicUpload.name, BasicUpload);
6   -};
7   -
  4 +withInstall(BasicUpload);
8 5 export { BasicUpload };
... ...
src/components/Verify/index.ts
1   -import BasicDragVerifyLib from './src/DragVerify';
2   -import RotateDragVerifyLib from './src/ImgRotate';
  1 +import BasicDragVerify from './src/DragVerify';
  2 +import RotateDragVerify from './src/ImgRotate';
3 3 import { withInstall } from '../util';
4 4  
  5 +withInstall(BasicDragVerify, RotateDragVerify);
  6 +
5 7 export * from './src/types';
6 8  
7   -export const RotateDragVerify = withInstall(RotateDragVerifyLib);
8   -export const BasicDragVerify = withInstall(BasicDragVerifyLib);
  9 +export { BasicDragVerify, RotateDragVerify };
... ...
src/components/VirtualScroll/index.ts
1   -import VirtualScrollLib from './src/index';
  1 +import VirtualScroll from './src/index';
2 2 import { withInstall } from '../util';
3 3  
4   -export const VirtualScroll = withInstall(VirtualScrollLib);
  4 +withInstall(VirtualScroll);
  5 +export { VirtualScroll };
... ...
src/components/util.ts
1   -import type { VNodeChild, Plugin } from 'vue';
  1 +import type { VNodeChild } from 'vue';
2 2 import type { App } from 'vue';
3 3  
4   -export function withInstall<T>(component: T) {
5   - const comp = component as any;
6   - comp.install = (app: App) => {
7   - app.component(comp.displayName || comp.name, comp);
8   - };
9   - return comp as T & Plugin;
  4 +export function withInstall(...components: any[]) {
  5 + components.forEach((comp) => {
  6 + comp.install = (app: App) => {
  7 + app.component(comp.displayName || comp.name, comp);
  8 + };
  9 + });
10 10 }
11 11  
12 12 export function convertToUnit(
... ...
src/design/var/index.less
... ... @@ -2,6 +2,8 @@
2 2 @import 'easing';
3 3 @import 'breakpoint';
4 4  
  5 +@namespace: vben;
  6 +
5 7 // tabs
6 8 @multiple-height: 30px;
7 9  
... ...
src/hooks/core/useContext.ts
1   -import { InjectionKey, provide, inject, reactive, readonly } from 'vue';
  1 +import {
  2 + InjectionKey,
  3 + provide,
  4 + inject,
  5 + reactive,
  6 + readonly as defineReadonly,
  7 + defineComponent,
  8 + UnwrapRef,
  9 +} from 'vue';
2 10  
3   -export const createContext = <T>(
4   - context: any,
5   - contextInjectKey: InjectionKey<T> = Symbol(),
6   - _readonly = true
7   -) => {
8   - const state = reactive({ ...context });
  11 +export interface CreateContextOptions {
  12 + readonly?: boolean;
  13 + createProvider?: boolean;
  14 +}
9 15  
10   - const provideData = _readonly ? readonly(state) : state;
11   - provide(contextInjectKey, provideData);
  16 +type ShallowUnwrap<T> = {
  17 + [P in keyof T]: UnwrapRef<T[P]>;
12 18 };
13 19  
  20 +export function createContext<T>(
  21 + context: any,
  22 + key: InjectionKey<T> = Symbol(),
  23 + options: CreateContextOptions = {}
  24 +) {
  25 + const { readonly = true, createProvider = false } = options;
  26 +
  27 + const state = reactive(context);
  28 +
  29 + const provideData = readonly ? defineReadonly(state) : state;
  30 + !createProvider && provide(key, provideData);
  31 +
  32 + const Provider = createProvider
  33 + ? defineComponent({
  34 + name: 'Provider',
  35 + inheritAttrs: false,
  36 + setup(_, { slots }) {
  37 + provide(key, provideData);
  38 + return () => slots.default?.();
  39 + },
  40 + })
  41 + : null;
  42 +
  43 + return { Provider, state };
  44 +}
  45 +
14 46 export const useContext = <T>(
15   - contextInjectKey: InjectionKey<T> = Symbol(),
  47 + key: InjectionKey<T> = Symbol(),
16 48 defaultValue?: any,
17   - _readonly = true
18   -): T => {
19   - const state = inject(contextInjectKey, defaultValue || {});
20   - return _readonly ? readonly(state) : state;
  49 + readonly = false
  50 +): ShallowUnwrap<T> => {
  51 + const state = inject(key, defaultValue || {});
  52 +
  53 + return readonly ? defineReadonly(state) : state;
21 54 };
... ...
src/hooks/setting/useMenuSetting.ts
... ... @@ -39,8 +39,6 @@ export function useMenuSetting() {
39 39  
40 40 const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
41 41  
42   - const getCollapsedShowSearch = computed(() => unref(getMenuSetting).collapsedShowSearch);
43   -
44 42 const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
45 43  
46 44 const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
... ... @@ -63,13 +61,6 @@ export function useMenuSetting() {
63 61 return unref(getTrigger) === TriggerEnum.HEADER;
64 62 });
65 63  
66   - const getShowSearch = computed(() => {
67   - return (
68   - unref(getMenuSetting).showSearch &&
69   - !(unref(getMenuType) === MenuTypeEnum.MIX && unref(getMenuMode) === MenuModeEnum.HORIZONTAL)
70   - );
71   - });
72   -
73 64 const getIsHorizontal = computed(() => {
74 65 return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
75 66 });
... ... @@ -119,9 +110,7 @@ export function useMenuSetting() {
119 110 getMenuTheme,
120 111 getCanDrag,
121 112 getIsHorizontal,
122   - getShowSearch,
123 113 getCollapsedShowTitle,
124   - getCollapsedShowSearch,
125 114 getIsSidebarType,
126 115 getAccordion,
127 116 getShowTopMenu,
... ...
src/hooks/web/useDesign.ts 0 → 100644
  1 +import { useAppProviderContext } from '/@/components/Application';
  2 +import { computed } from 'vue';
  3 +// import { useCssModule, reactive } from 'vue';
  4 +export function useDesign(scope: string) {
  5 + const values = useAppProviderContext();
  6 + // const style = cssModule ? useCssModule() : {};
  7 +
  8 + // if (cssModule) {
  9 + // Object.keys(style).forEach((key) => {
  10 + // const moduleCls = style[key];
  11 + // style[key] = `${cls}-${moduleCls}`;
  12 + // });
  13 + // }
  14 + return {
  15 + prefixCls: computed(() => `${values.prefixCls}-${scope}`),
  16 + prefixVar: values.prefixCls,
  17 + // style,
  18 + };
  19 +}
... ...
src/hooks/web/useLocale.ts
... ... @@ -27,7 +27,6 @@ export function useLocale() {
27 27 setLocalSetting({ lang });
28 28 // i18n.global.setLocaleMessage(locale, messages);
29 29  
30   - antConfigLocaleRef.value = { a: 1 };
31 30 switch (lang) {
32 31 // Simplified Chinese
33 32 case 'zh_CN':
... ...
src/layouts/default/header/LayoutHeader.tsx
... ... @@ -188,7 +188,6 @@ export default defineComponent({
188 188 theme={unref(getHeaderTheme)}
189 189 splitType={unref(getSplitType)}
190 190 menuMode={unref(getMenuMode)}
191   - showSearch={false}
192 191 />
193 192 </div>
194 193 )}
... ...
src/layouts/default/menu/index.tsx
... ... @@ -27,9 +27,6 @@ export default defineComponent({
27 27 default: MenuSplitTyeEnum.NONE,
28 28 },
29 29  
30   - // Whether to show search box
31   - showSearch: propTypes.bool.def(true),
32   -
33 30 isHorizontal: propTypes.bool,
34 31 // menu Mode
35 32 menuMode: {
... ... @@ -42,11 +39,9 @@ export default defineComponent({
42 39  
43 40 const {
44 41 setMenuSetting,
45   - getShowSearch,
46 42 getMenuMode,
47 43 getMenuType,
48 44 getCollapsedShowTitle,
49   - getCollapsedShowSearch,
50 45 getIsSidebarType,
51 46 getMenuTheme,
52 47 getCollapsed,
... ... @@ -65,14 +60,6 @@ export default defineComponent({
65 60  
66 61 const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP);
67 62  
68   - const showSearch = computed(() => {
69   - return (
70   - unref(getShowSearch) &&
71   - props.showSearch &&
72   - (unref(getCollapsedShowSearch) ? true : !unref(getCollapsed))
73   - );
74   - });
75   -
76 63 /**
77 64 * click menu
78 65 * @param menu
... ... @@ -122,7 +109,6 @@ export default defineComponent({
122 109 collapsedShowTitle={unref(getCollapsedShowTitle)}
123 110 theme={unref(getComputedMenuTheme)}
124 111 showLogo={unref(showLogo)}
125   - search={unref(showSearch)}
126 112 items={unref(menusRef)}
127 113 flatItems={unref(flatMenusRef)}
128 114 accordion={unref(getAccordion)}
... ...
src/layouts/default/setting/enum.ts
... ... @@ -21,7 +21,6 @@ export enum HandlerEnum {
21 21 MENU_SHOW_SIDEBAR,
22 22 MENU_THEME,
23 23 MENU_SPLIT,
24   - MENU_SHOW_SEARCH,
25 24 MENU_FIXED,
26 25  
27 26 // header
... ...
src/layouts/default/setting/handler.ts
... ... @@ -63,9 +63,6 @@ export function handler(event: HandlerEnum, value: any): DeepPartial&lt;ProjectConf
63 63 case HandlerEnum.MENU_FIXED:
64 64 return { menuSetting: { fixed: value } };
65 65  
66   - case HandlerEnum.MENU_SHOW_SEARCH:
67   - return { menuSetting: { showSearch: value } };
68   -
69 66 // ============transition==================
70 67 case HandlerEnum.OPEN_PAGE_LOADING:
71 68 appStore.commitPageLoadingState(false);
... ...
src/layouts/default/sider/index.less
... ... @@ -15,7 +15,6 @@
15 15 }
16 16  
17 17 &:not(.ant-layout-sider-dark) {
18   - // border-right: 1px solid @border-color-light;
19 18 box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
20 19 }
21 20  
... ...
src/router/constant.ts
... ... @@ -25,7 +25,6 @@ export const getParentLayout = (name: string) =&gt; {
25 25 export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = {
26 26 path: '/:path(.*)*',
27 27 name: 'ErrorPage',
28   - redirect: '/error/404',
29 28 component: LAYOUT,
30 29 meta: {
31 30 title: 'ErrorPage',
... ... @@ -33,7 +32,7 @@ export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = {
33 32 },
34 33 children: [
35 34 {
36   - path: '/error/404',
  35 + path: '/:path(.*)*',
37 36 name: 'ErrorPage',
38 37 component: EXCEPTION_COMPONENT,
39 38 meta: {
... ...
src/router/menus/index.ts
... ... @@ -21,6 +21,9 @@ Object.keys(modules).forEach((key) =&gt; {
21 21 // ===========================
22 22 // ==========Helper===========
23 23 // ===========================
  24 +const isBackMode = () => {
  25 + return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
  26 +};
24 27  
25 28 const staticMenus: Menu[] = [];
26 29 (() => {
... ... @@ -33,10 +36,6 @@ const staticMenus: Menu[] = [];
33 36 }
34 37 })();
35 38  
36   -const isBackMode = () => {
37   - return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
38   -};
39   -
40 39 async function getAsyncMenus() {
41 40 // 前端角色控制菜单 直接取菜单文件
42 41 if (!isBackMode()) {
... ...
src/settings/colorSetting.ts
... ... @@ -17,9 +17,11 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
17 17 export const SIDE_BAR_BG_COLOR_LIST: string[] = [
18 18 '#273352',
19 19 '#ffffff',
  20 + '#191b24',
20 21 '#191a23',
21 22 '#001529',
22 23 '#304156',
  24 + '#001628',
23 25 '#28333E',
24 26 '#344058',
25 27 ];
... ...
src/settings/projectSetting.ts
... ... @@ -89,8 +89,6 @@ const setting: ProjectConfig = {
89 89 show: true,
90 90 // Whether to show dom
91 91 hidden: true,
92   - // Whether to show search box
93   - showSearch: true,
94 92 // Menu width
95 93 menuWidth: 210,
96 94 // Menu mode
... ...
src/types/config.d.ts
... ... @@ -9,7 +9,6 @@ export interface MenuSetting {
9 9 collapsed: boolean;
10 10 collapsedShowTitle: boolean;
11 11 canDrag: boolean;
12   - showSearch: boolean;
13 12 show: boolean;
14 13 hidden: boolean;
15 14 split: boolean;
... ...