vben
2020-12-07 74e62cbc712bdd4d4826e5fe80f537d87e44ffce
feat: add useDesign
2个文件已删除
4个文件已添加
45个文件已修改
1 文件已重命名
645 ■■■■■ 已修改文件
.ls-lint.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Application/index.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Application/src/AppLocalePicker.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Application/src/AppLogo.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Application/src/AppProvider.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Application/src/useAppContext.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Authority/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Basic/index.ts 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Button/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ClickOutSide/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Container/index.ts 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/CountTo/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Description/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Drawer/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Dropdown/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Excel/index.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Form/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Loading/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Markdown/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/BasicMenu.tsx 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/BasicMenu.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/MenuContent.tsx 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/SearchInput.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/hooks/useSearchInput.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/props.ts 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/types.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Menu/src/useOpenKeys.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Modal/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Page/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/StrengthMeter/index.tsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Tinymce/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Upload/index.ts 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Verify/index.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/VirtualScroll/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/util.ts 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/design/var/index.less 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/core/useContext.ts 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/setting/useMenuSetting.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/web/useDesign.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/web/useLocale.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/header/LayoutHeader.tsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/menu/index.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/setting/enum.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/setting/handler.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/sider/index.less 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/constant.ts 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/menus/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/settings/colorSetting.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/settings/projectSetting.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/types/config.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.ls-lint.yml
@@ -3,6 +3,7 @@
    .js: kebab-case | PascalCase
    .vue: PascalCase | regex:^index
    .ts: camelCase | PascalCase
    .tsx: camelCase | PascalCase
    .d.ts: kebab-case
    .mock.ts: kebab-case
    .data.ts: camelCase | kebab-case
src/App.vue
@@ -4,7 +4,9 @@
    :locale="antConfigLocale"
    :transform-cell-text="transformCellText"
  >
    <router-view />
    <AppProvider>
      <router-view />
    </AppProvider>
  </ConfigProvider>
</template>
@@ -17,9 +19,11 @@
  import { useLockPage } from '/@/hooks/web/useLockPage';
  import { useLocale } from '/@/hooks/web/useLocale';
  import { AppProvider } from '/@/components/Application';
  export default defineComponent({
    name: 'App',
    components: { ConfigProvider },
    components: { ConfigProvider, AppProvider },
    setup() {
      // Initialize vuex internal system configuration
      initAppConfigStore();
src/components/Application/index.ts
@@ -1,6 +1,10 @@
import AppLocalePickerLib from './src/AppLocalePicker.vue';
import AppLogoLib from './src/AppLogo.vue';
import AppLocalePicker from './src/AppLocalePicker.vue';
import AppLogo from './src/AppLogo.vue';
import AppProvider from './src/AppProvider.vue';
import { withInstall } from '../util';
export const AppLocalePicker = withInstall(AppLocalePickerLib);
export const AppLogo = withInstall(AppLogoLib);
withInstall(AppLocalePicker, AppLogo, AppProvider);
export { useAppProviderContext } from './src/useAppContext';
export { AppLocalePicker, AppLogo, AppProvider };
src/components/Application/src/AppLocalePicker.vue
@@ -69,8 +69,8 @@
  });
</script>
<style lang="less">
  .app-locale-picker-overlay {
<style lang="less" scoped>
  :global(.app-locale-picker-overlay) {
    .ant-dropdown-menu-item {
      min-width: 160px;
    }
src/components/Application/src/AppLogo.vue
@@ -4,12 +4,14 @@
-->
<template>
  <div
    class="app-logo anticon"
    :class="{ theme, 'collapsed-show-title': getCollapsedShowTitle }"
    class="anticon"
    :class="[prefixCls, theme, { 'collapsed-show-title': getCollapsedShowTitle }]"
    @click="handleGoHome"
  >
    <img src="/@/assets/images/logo.png" />
    <div class="app-logo__title ml-2 ellipsis" v-show="showTitle">{{ globSetting.title }}</div>
    <div class="ml-2 ellipsis" :class="[`${prefixCls}__title`]" v-show="showTitle">
      {{ globSetting.title }}
    </div>
  </div>
</template>
<script lang="ts">
@@ -23,6 +25,8 @@
  import { propTypes } from '/@/utils/propTypes';
  import { useDesign } from '/@/hooks/web/useDesign';
  export default defineComponent({
    name: 'AppLogo',
    props: {
@@ -34,6 +38,8 @@
      showTitle: propTypes.bool.def(true),
    },
    setup() {
      const { prefixCls } = useDesign('app-logo');
      const { getCollapsedShowTitle } = useMenuSetting();
      const globSetting = useGlobSetting();
@@ -48,17 +54,19 @@
        handleGoHome,
        globSetting,
        getCollapsedShowTitle,
        prefixCls,
      };
    },
  });
</script>
<style lang="less" scoped>
  @import (reference) '../../../design/index.less';
  @prefix-cls: ~'@{namespace}-app-logo';
  .app-logo {
  .@{prefix-cls} {
    display: flex;
    align-items: center;
    padding-left: 10px;
    padding-left: 12px;
    cursor: pointer;
    &.collapsed-show-title {
src/components/Application/src/AppProvider.vue
New file
@@ -0,0 +1,24 @@
<template>
  <slot />
</template>
<script lang="ts">
  import type { PropType } from 'vue';
  import { defineComponent, toRefs } from 'vue';
  import { createAppProviderContext } from './useAppContext';
  export default defineComponent({
    name: 'AppProvider',
    inheritAttrs: false,
    props: {
      prefixCls: {
        type: String as PropType<string>,
        default: 'vben',
      },
    },
    setup(props) {
      const { prefixCls } = toRefs(props);
      createAppProviderContext({ prefixCls });
      return {};
    },
  });
</script>
src/components/Application/src/useAppContext.ts
New file
@@ -0,0 +1,16 @@
import { InjectionKey, Ref } from 'vue';
import { createContext, useContext } from '/@/hooks/core/useContext';
export interface AppProviderContextProps {
  prefixCls: Ref<string>;
}
const key: InjectionKey<AppProviderContextProps> = Symbol();
export function createAppProviderContext(context: AppProviderContextProps) {
  return createContext<AppProviderContextProps>(context, key);
}
export function useAppProviderContext() {
  return useContext<AppProviderContextProps>(key);
}
src/components/Authority/index.ts
@@ -1,5 +1,7 @@
import AuthorityLib from './src/index.vue';
import Authority from './src/index.vue';
import { withInstall } from '../util';
export const Authority = withInstall(AuthorityLib);
withInstall(Authority);
export { Authority };
src/components/Basic/index.ts
@@ -1,9 +1,9 @@
import BasicArrowLib from './src/BasicArrow.vue';
import BasicHelpLib from './src/BasicHelp.vue';
import BasicTitleLib from './src/BasicTitle.vue';
import BasicArrow from './src/BasicArrow.vue';
import BasicHelp from './src/BasicHelp.vue';
import BasicTitle from './src/BasicTitle.vue';
import { withInstall } from '../util';
export const BasicArrow = withInstall(BasicArrowLib);
export const BasicHelp = withInstall(BasicHelpLib);
export const BasicTitle = withInstall(BasicTitleLib);
withInstall(BasicArrow, BasicHelp, BasicTitle);
export { BasicArrow, BasicHelp, BasicTitle };
src/components/Button/index.ts
@@ -1,4 +1,6 @@
import ButtonLib from './src/BasicButton.vue';
import Button from './src/BasicButton.vue';
import { withInstall } from '../util';
export const Button = withInstall(ButtonLib);
withInstall(Button);
export { Button };
src/components/ClickOutSide/index.ts
@@ -1,4 +1,6 @@
import ClickOutSideLib from './src/index.vue';
import ClickOutSide from './src/index.vue';
import { withInstall } from '../util';
export const ClickOutSide = withInstall(ClickOutSideLib);
withInstall(ClickOutSide);
export { ClickOutSide };
src/components/Container/index.ts
@@ -1,10 +1,10 @@
import ScrollContainerLib from './src/ScrollContainer.vue';
import CollapseContainerLib from './src/collapse/CollapseContainer.vue';
import LazyContainerLib from './src/LazyContainer.vue';
import ScrollContainer from './src/ScrollContainer.vue';
import CollapseContainer from './src/collapse/CollapseContainer.vue';
import LazyContainer from './src/LazyContainer.vue';
import { withInstall } from '../util';
withInstall(ScrollContainer, CollapseContainer, LazyContainer);
export * from './src/types';
export const ScrollContainer = withInstall(ScrollContainerLib);
export const CollapseContainer = withInstall(CollapseContainerLib);
export const LazyContainer = withInstall(LazyContainerLib);
export { ScrollContainer, CollapseContainer, LazyContainer };
src/components/CountTo/index.ts
@@ -1,6 +1,7 @@
// Transform vue-count-to to support vue3 version
import CountToLib from './src/index.vue';
import CountTo from './src/index.vue';
import { withInstall } from '../util';
export const CountTo = withInstall(CountToLib);
withInstall(CountTo);
export { CountTo };
src/components/Description/index.ts
@@ -1,8 +1,9 @@
import DescriptionLib from './src/index';
import Description from './src/index';
import { withInstall } from '../util';
withInstall(Description);
export * from './src/types';
export { useDescription } from './src/useDescription';
export const Description = withInstall(DescriptionLib);
export { Description };
src/components/Drawer/index.ts
@@ -1,6 +1,7 @@
import BasicDrawerLib from './src/BasicDrawer';
import BasicDrawer from './src/BasicDrawer';
import { withInstall } from '../util';
withInstall(BasicDrawer);
export * from './src/types';
export { useDrawer, useDrawerInner } from './src/useDrawer';
export const BasicDrawer = withInstall(BasicDrawerLib);
export { BasicDrawer };
src/components/Dropdown/index.ts
@@ -1,6 +1,7 @@
import DropdownLib from './src/Dropdown';
import Dropdown from './src/Dropdown';
import { withInstall } from '../util';
withInstall(Dropdown);
export * from './src/types';
export const Dropdown = withInstall(DropdownLib);
export { Dropdown };
src/components/Excel/index.ts
@@ -1,11 +1,12 @@
import ImportExcelLib from './src/ImportExcel.vue';
import ExportExcelModelLib from './src/ExportExcelModel.vue';
import ImportExcel from './src/ImportExcel.vue';
import ExportExcelModel from './src/ExportExcelModel.vue';
import { withInstall } from '../util';
withInstall(ImportExcel, ExportExcelModel);
export * from './src/types';
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';
export const ImportExcel = withInstall(ImportExcelLib);
export const ExportExcelModel = withInstall(ExportExcelModelLib);
export { ImportExcel, ExportExcelModel };
src/components/Form/index.ts
@@ -1,5 +1,7 @@
import BasicFormLib from './src/BasicForm.vue';
import BasicForm from './src/BasicForm.vue';
import { withInstall } from '../util';
withInstall(BasicForm);
export * from './src/types/form';
export * from './src/types/formItem';
@@ -7,4 +9,4 @@
export { useComponentRegister } from './src/hooks/useComponentRegister';
export { useForm } from './src/hooks/useForm';
export const BasicForm = withInstall(BasicFormLib);
export { BasicForm };
src/components/Loading/index.ts
@@ -1,8 +1,9 @@
import './src/indicator';
import LoadingLib from './src/index.vue';
import Loading from './src/index.vue';
import { withInstall } from '../util';
withInstall(Loading);
export { useLoading } from './src/useLoading';
export { createLoading } from './src/createLoading';
export const Loading = withInstall(LoadingLib);
export { Loading };
src/components/Markdown/index.ts
@@ -1,7 +1,9 @@
import MarkDownLib from './src/index.vue';
import MarkDown from './src/index.vue';
import { withInstall } from '../util';
withInstall(MarkDown);
export * from './src/types';
export const MarkDown = withInstall(MarkDownLib);
export { MarkDown };
src/components/Menu/index.ts
@@ -1,4 +1,5 @@
import BasicMenuLib from './src/BasicMenu';
import BasicMenu from './src/BasicMenu';
import { withInstall } from '../util';
export const BasicMenu = withInstall(BasicMenuLib);
withInstall(BasicMenu);
export { BasicMenu };
src/components/Menu/src/BasicMenu.tsx
@@ -15,7 +15,6 @@
  ComputedRef,
} from 'vue';
import { Menu } from 'ant-design-vue';
import SearchInput from './SearchInput.vue';
import MenuContent from './MenuContent';
// import { ScrollContainer } from '/@/components/Container';
@@ -24,8 +23,7 @@
import { appStore } from '/@/store/modules/app';
import { useSearchInput } from './hooks/useSearchInput';
import { useOpenKeys } from './hooks/useOpenKeys';
import { useOpenKeys } from './useOpenKeys';
import { useRouter } from 'vue-router';
import { isFunction } from '/@/utils/is';
@@ -43,51 +41,39 @@
  emits: ['menuClick'],
  setup(props, { slots, emit }) {
    const currentParentPath = ref('');
    const menuState = reactive<MenuState>({
      defaultSelectedKeys: [],
      mode: props.mode,
      theme: computed(() => props.theme) as ComputedRef<ThemeEnum>,
      openKeys: [],
      searchValue: '',
      selectedKeys: [],
      collapsedOpenKeys: [],
    });
    const { getCollapsed } = useMenuSetting();
    const { currentRoute } = useRouter();
    const { items, flatItems, isAppMenu, mode, accordion } = toRefs(props);
    const { handleInputChange, handleInputClick } = useSearchInput({
      flatMenusRef: flatItems,
      emit: emit,
      menuState,
      handleMenuChange,
    });
    const { items, flatItems, mode, accordion } = toRefs(props);
    const { handleOpenChange, resetKeys, setOpenKeys } = useOpenKeys(
      menuState,
      items,
      flatItems,
      isAppMenu,
      mode,
      accordion
    );
    const getOpenKeys = computed(() => {
      if (props.isAppMenu) {
        return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
      }
      return menuState.openKeys;
      return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
    });
    // menu外层样式
    const getMenuWrapStyle = computed((): any => {
      const { showLogo, search } = props;
      const { showLogo } = props;
      let offset = 0;
      if (search) {
        offset += 54;
      }
      if (showLogo) {
        offset += 46;
      }
@@ -110,7 +96,7 @@
        cls.push('basic-menu__sidebar-hor');
      }
      if (!props.isHorizontal && props.isAppMenu && appStore.getProjectConfig.menuSetting.split) {
      if (!props.isHorizontal && appStore.getProjectConfig.menuSetting.split) {
        cls.push('basic-menu__second');
      }
      return cls;
@@ -197,7 +183,6 @@
                  level={index}
                  isHorizontal={props.isHorizontal}
                  showTitle={unref(showTitle)}
                  searchValue={menuState.searchValue}
                />,
              ]}
            </Menu.Item>
@@ -212,7 +197,6 @@
                  item={menu}
                  level={index}
                  isHorizontal={props.isHorizontal}
                  searchValue={menuState.searchValue}
                />,
              ],
              default: () => renderMenuItem(menu.children, index + 1),
@@ -227,11 +211,9 @@
      const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState;
      const inlineCollapsedObj = isInline
        ? props.isAppMenu
          ? {
              inlineCollapsed: unref(getCollapsed),
            }
          : { inlineCollapsed: props.inlineCollapsed }
        ? {
            inlineCollapsed: unref(getCollapsed),
          }
        : {};
      return (
        <Menu
@@ -267,17 +249,8 @@
      ) : (
        <section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}>
          {getSlot(slots, 'header')}
          <SearchInput
            class={!props.search ? 'hidden' : ''}
            theme={props.theme as ThemeEnum}
            onChange={handleInputChange}
            onClick={handleInputClick}
            collapsed={unref(getCollapsed)}
          />
          {/* <section style={unref(getMenuWrapStyle)}> */}
          <section style={unref(getMenuWrapStyle)} class="basic-menu__content">
            {/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
            {renderMenu()}
          </section>
        </section>
src/components/Menu/src/BasicMenu.vue
New file
@@ -0,0 +1,11 @@
<template>
  <div> </div>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  export default defineComponent({
    setup() {
      return {};
    },
  });
</script>
src/components/Menu/src/MenuContent.tsx
@@ -8,11 +8,6 @@
export default defineComponent({
  name: 'MenuContent',
  props: {
    searchValue: {
      type: String as PropType<string>,
      default: '',
    },
    item: {
      type: Object as PropType<MenuType>,
      default: null,
@@ -35,11 +30,7 @@
  setup(props) {
    const { t } = useI18n();
    const getI18nName = computed(() => {
      const { name } = props.item;
      return t(name);
    });
    const getI18nName = computed(() => t(props.item?.name));
    /**
     * @description: 渲染图标
     */
@@ -71,28 +62,18 @@
      const { showTitle } = props;
      const { icon } = props.item;
      const name = unref(getI18nName);
      const searchValue = props.searchValue || '';
      const index = name.indexOf(searchValue);
      const beforeStr = name.substr(0, index);
      const afterStr = name.substr(index + searchValue.length);
      const cls = showTitle ? ['show-title'] : ['basic-menu__name'];
      return (
        <>
          {renderIcon(icon!)}
          {index > -1 && searchValue ? (
            <span class={cls}>
              {beforeStr}
              <span class={`basic-menu__keyword`}>{searchValue}</span>
              {afterStr}
            </span>
          ) : (
          {
            <span class={[cls]}>
              {name}
              {renderTag()}
            </span>
          )}
          }
        </>
      );
    };
src/components/Menu/src/SearchInput.vue
File was deleted
src/components/Menu/src/hooks/useSearchInput.ts
File was deleted
src/components/Menu/src/props.ts
@@ -20,11 +20,7 @@
    type: Boolean as PropType<boolean>,
    default: false,
  },
  // 是否显示搜索框
  search: {
    type: Boolean as PropType<boolean>,
    default: true,
  },
  // 最好是4 倍数
  inlineIndent: {
    type: Number as PropType<number>,
@@ -51,10 +47,7 @@
    type: Boolean as PropType<boolean>,
    default: false,
  },
  isAppMenu: {
    type: Boolean as PropType<boolean>,
    default: true,
  },
  isHorizontal: {
    type: Boolean as PropType<boolean>,
    default: false,
src/components/Menu/src/types.ts
@@ -17,9 +17,6 @@
  // 展开数组
  openKeys: string[];
  // 搜索值
  searchValue: string;
  // 当前选中的菜单项 key 数组
  selectedKeys: string[];
src/components/Menu/src/useOpenKeys.ts
File was renamed from src/components/Menu/src/hooks/useOpenKeys.ts
@@ -1,6 +1,6 @@
import { MenuModeEnum } from '/@/enums/menuEnum';
import type { Menu as MenuType } from '/@/router/types';
import type { MenuState } from '../types';
import type { MenuState } from './types';
import type { Ref } from 'vue';
import { unref } from 'vue';
@@ -12,14 +12,11 @@
  menuState: MenuState,
  menus: Ref<MenuType[]>,
  flatMenusRef: Ref<MenuType[]>,
  isAppMenu: Ref<boolean>,
  mode: Ref<MenuModeEnum>,
  accordion: Ref<boolean>
) {
  const { getCollapsed } = useMenuSetting();
  /**
   * @description:设置展开
   */
  function setOpenKeys(menu: MenuType) {
    const flatMenus = unref(flatMenusRef);
    if (!unref(accordion)) {
@@ -50,7 +47,7 @@
          rootSubMenuKeys.push(path);
        }
      }
      if (!unref(getCollapsed) || !unref(isAppMenu)) {
      if (!unref(getCollapsed)) {
        const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1);
        if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) {
          menuState.openKeys = openKeys;
src/components/Modal/index.ts
@@ -1,8 +1,10 @@
import './src/index.less';
import BasicModalLib from './src/BasicModal';
import BasicModal from './src/BasicModal';
import { withInstall } from '../util';
withInstall(BasicModal);
export { useModalContext } from './src/useModalContext';
export { useModal, useModalInner } from './src/useModal';
export * from './src/types';
export const BasicModal = withInstall(BasicModalLib);
export { BasicModal };
src/components/Page/index.ts
@@ -1,4 +1,5 @@
import PageFooterLib from './src/PageFooter.vue';
import PageFooter from './src/PageFooter.vue';
import { withInstall } from '../util';
export const PageFooter = withInstall(PageFooterLib);
withInstall(PageFooter);
export { PageFooter };
src/components/StrengthMeter/index.tsx
@@ -1,4 +1,5 @@
import StrengthMeterLib from './src/index';
import StrengthMeter from './src/index';
import { withInstall } from '../util';
export const StrengthMeter = withInstall(StrengthMeterLib);
withInstall(StrengthMeter);
export { StrengthMeter };
src/components/Tinymce/index.ts
@@ -1,4 +1,5 @@
import TinymceLib from './src/Editor.vue';
import Tinymce from './src/Editor.vue';
import { withInstall } from '../util';
export const Tinymce = withInstall(TinymceLib);
withInstall(Tinymce);
export { Tinymce };
src/components/Upload/index.ts
@@ -1,8 +1,5 @@
import type { App } from 'vue';
import BasicUpload from './src/BasicUpload.vue';
import { withInstall } from '../util';
export default (app: App): void => {
  app.component(BasicUpload.name, BasicUpload);
};
withInstall(BasicUpload);
export { BasicUpload };
src/components/Verify/index.ts
@@ -1,8 +1,9 @@
import BasicDragVerifyLib from './src/DragVerify';
import RotateDragVerifyLib from './src/ImgRotate';
import BasicDragVerify from './src/DragVerify';
import RotateDragVerify from './src/ImgRotate';
import { withInstall } from '../util';
withInstall(BasicDragVerify, RotateDragVerify);
export * from './src/types';
export const RotateDragVerify = withInstall(RotateDragVerifyLib);
export const BasicDragVerify = withInstall(BasicDragVerifyLib);
export { BasicDragVerify, RotateDragVerify };
src/components/VirtualScroll/index.ts
@@ -1,4 +1,5 @@
import VirtualScrollLib from './src/index';
import VirtualScroll from './src/index';
import { withInstall } from '../util';
export const VirtualScroll = withInstall(VirtualScrollLib);
withInstall(VirtualScroll);
export { VirtualScroll };
src/components/util.ts
@@ -1,12 +1,12 @@
import type { VNodeChild, Plugin } from 'vue';
import type { VNodeChild } from 'vue';
import type { App } from 'vue';
export function withInstall<T>(component: T) {
  const comp = component as any;
  comp.install = (app: App) => {
    app.component(comp.displayName || comp.name, comp);
  };
  return comp as T & Plugin;
export function withInstall(...components: any[]) {
  components.forEach((comp) => {
    comp.install = (app: App) => {
      app.component(comp.displayName || comp.name, comp);
    };
  });
}
export function convertToUnit(
src/design/var/index.less
@@ -2,6 +2,8 @@
@import 'easing';
@import 'breakpoint';
@namespace: vben;
// tabs
@multiple-height: 30px;
src/hooks/core/useContext.ts
@@ -1,21 +1,54 @@
import { InjectionKey, provide, inject, reactive, readonly } from 'vue';
import {
  InjectionKey,
  provide,
  inject,
  reactive,
  readonly as defineReadonly,
  defineComponent,
  UnwrapRef,
} from 'vue';
export const createContext = <T>(
  context: any,
  contextInjectKey: InjectionKey<T> = Symbol(),
  _readonly = true
) => {
  const state = reactive({ ...context });
export interface CreateContextOptions {
  readonly?: boolean;
  createProvider?: boolean;
}
  const provideData = _readonly ? readonly(state) : state;
  provide(contextInjectKey, provideData);
type ShallowUnwrap<T> = {
  [P in keyof T]: UnwrapRef<T[P]>;
};
export function createContext<T>(
  context: any,
  key: InjectionKey<T> = Symbol(),
  options: CreateContextOptions = {}
) {
  const { readonly = true, createProvider = false } = options;
  const state = reactive(context);
  const provideData = readonly ? defineReadonly(state) : state;
  !createProvider && provide(key, provideData);
  const Provider = createProvider
    ? defineComponent({
        name: 'Provider',
        inheritAttrs: false,
        setup(_, { slots }) {
          provide(key, provideData);
          return () => slots.default?.();
        },
      })
    : null;
  return { Provider, state };
}
export const useContext = <T>(
  contextInjectKey: InjectionKey<T> = Symbol(),
  key: InjectionKey<T> = Symbol(),
  defaultValue?: any,
  _readonly = true
): T => {
  const state = inject(contextInjectKey, defaultValue || {});
  return _readonly ? readonly(state) : state;
  readonly = false
): ShallowUnwrap<T> => {
  const state = inject(key, defaultValue || {});
  return readonly ? defineReadonly(state) : state;
};
src/hooks/setting/useMenuSetting.ts
@@ -39,8 +39,6 @@
  const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
  const getCollapsedShowSearch = computed(() => unref(getMenuSetting).collapsedShowSearch);
  const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
  const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
@@ -61,13 +59,6 @@
    }
    return unref(getTrigger) === TriggerEnum.HEADER;
  });
  const getShowSearch = computed(() => {
    return (
      unref(getMenuSetting).showSearch &&
      !(unref(getMenuType) === MenuTypeEnum.MIX && unref(getMenuMode) === MenuModeEnum.HORIZONTAL)
    );
  });
  const getIsHorizontal = computed(() => {
@@ -119,9 +110,7 @@
    getMenuTheme,
    getCanDrag,
    getIsHorizontal,
    getShowSearch,
    getCollapsedShowTitle,
    getCollapsedShowSearch,
    getIsSidebarType,
    getAccordion,
    getShowTopMenu,
src/hooks/web/useDesign.ts
New file
@@ -0,0 +1,19 @@
import { useAppProviderContext } from '/@/components/Application';
import { computed } from 'vue';
// import { useCssModule, reactive } from 'vue';
export function useDesign(scope: string) {
  const values = useAppProviderContext();
  // const style = cssModule ? useCssModule() : {};
  // if (cssModule) {
  //   Object.keys(style).forEach((key) => {
  //     const moduleCls = style[key];
  //     style[key] = `${cls}-${moduleCls}`;
  //   });
  // }
  return {
    prefixCls: computed(() => `${values.prefixCls}-${scope}`),
    prefixVar: values.prefixCls,
    // style,
  };
}
src/hooks/web/useLocale.ts
@@ -27,7 +27,6 @@
    setLocalSetting({ lang });
    // i18n.global.setLocaleMessage(locale, messages);
    antConfigLocaleRef.value = { a: 1 };
    switch (lang) {
      // Simplified Chinese
      case 'zh_CN':
src/layouts/default/header/LayoutHeader.tsx
@@ -188,7 +188,6 @@
                theme={unref(getHeaderTheme)}
                splitType={unref(getSplitType)}
                menuMode={unref(getMenuMode)}
                showSearch={false}
              />
            </div>
          )}
src/layouts/default/menu/index.tsx
@@ -27,9 +27,6 @@
      default: MenuSplitTyeEnum.NONE,
    },
    // Whether to show search box
    showSearch: propTypes.bool.def(true),
    isHorizontal: propTypes.bool,
    // menu Mode
    menuMode: {
@@ -42,11 +39,9 @@
    const {
      setMenuSetting,
      getShowSearch,
      getMenuMode,
      getMenuType,
      getCollapsedShowTitle,
      getCollapsedShowSearch,
      getIsSidebarType,
      getMenuTheme,
      getCollapsed,
@@ -64,14 +59,6 @@
    const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
    const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP);
    const showSearch = computed(() => {
      return (
        unref(getShowSearch) &&
        props.showSearch &&
        (unref(getCollapsedShowSearch) ? true : !unref(getCollapsed))
      );
    });
    /**
     * click menu
@@ -122,7 +109,6 @@
          collapsedShowTitle={unref(getCollapsedShowTitle)}
          theme={unref(getComputedMenuTheme)}
          showLogo={unref(showLogo)}
          search={unref(showSearch)}
          items={unref(menusRef)}
          flatItems={unref(flatMenusRef)}
          accordion={unref(getAccordion)}
src/layouts/default/setting/enum.ts
@@ -21,7 +21,6 @@
  MENU_SHOW_SIDEBAR,
  MENU_THEME,
  MENU_SPLIT,
  MENU_SHOW_SEARCH,
  MENU_FIXED,
  // header
src/layouts/default/setting/handler.ts
@@ -63,9 +63,6 @@
    case HandlerEnum.MENU_FIXED:
      return { menuSetting: { fixed: value } };
    case HandlerEnum.MENU_SHOW_SEARCH:
      return { menuSetting: { showSearch: value } };
    // ============transition==================
    case HandlerEnum.OPEN_PAGE_LOADING:
      appStore.commitPageLoadingState(false);
src/layouts/default/sider/index.less
@@ -15,7 +15,6 @@
  }
  &:not(.ant-layout-sider-dark) {
    // border-right: 1px solid @border-color-light;
    box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
  }
src/router/constant.ts
@@ -25,7 +25,6 @@
export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = {
  path: '/:path(.*)*',
  name: 'ErrorPage',
  redirect: '/error/404',
  component: LAYOUT,
  meta: {
    title: 'ErrorPage',
@@ -33,7 +32,7 @@
  },
  children: [
    {
      path: '/error/404',
      path: '/:path(.*)*',
      name: 'ErrorPage',
      component: EXCEPTION_COMPONENT,
      meta: {
src/router/menus/index.ts
@@ -21,6 +21,9 @@
// ===========================
// ==========Helper===========
// ===========================
const isBackMode = () => {
  return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
};
const staticMenus: Menu[] = [];
(() => {
@@ -32,10 +35,6 @@
    staticMenus.push(transformMenuModule(menu));
  }
})();
const isBackMode = () => {
  return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
};
async function getAsyncMenus() {
  // 前端角色控制菜单 直接取菜单文件
src/settings/colorSetting.ts
@@ -17,9 +17,11 @@
export const SIDE_BAR_BG_COLOR_LIST: string[] = [
  '#273352',
  '#ffffff',
  '#191b24',
  '#191a23',
  '#001529',
  '#304156',
  '#001628',
  '#28333E',
  '#344058',
];
src/settings/projectSetting.ts
@@ -89,8 +89,6 @@
    show: true,
    // Whether to show dom
    hidden: true,
    // Whether to show search box
    showSearch: true,
    // Menu width
    menuWidth: 210,
    // Menu mode
src/types/config.d.ts
@@ -9,7 +9,6 @@
  collapsed: boolean;
  collapsedShowTitle: boolean;
  canDrag: boolean;
  showSearch: boolean;
  show: boolean;
  hidden: boolean;
  split: boolean;