From 55e9d9fc2953643cec95c74b6ed34b0e68641fb6 Mon Sep 17 00:00:00 2001
From: Vben <anncwb@126.com>
Date: 星期三, 09 六月 2021 00:22:29 +0800
Subject: [PATCH] perf: optimize components and add comments

---
 src/components/Application/src/search/AppSearch.vue         |    2 
 src/components/Basic/src/BasicArrow.vue                     |   49 +-
 types/module.d.ts                                           |    4 
 src/components/Application/src/AppLogo.vue                  |   70 ++-
 src/components/Authority/src/Authority.vue                  |    3 
 src/components/Container/src/collapse/CollapseContainer.vue |   64 +-
 src/components/Button/src/PopConfirmButton.vue              |    2 
 src/components/Container/src/collapse/CollapseHeader.vue    |   23 
 src/components/CodeEditor/src/CodeEditor.vue                |   44 +-
 src/components/CodeEditor/src/codemirror/codemirror.css     |   59 --
 src/components/ClickOutSide/index.ts                        |    5 
 src/components/Application/src/search/AppSearchKeyItem.vue  |    4 
 src/components/Application/index.ts                         |   19 
 src/components/Button/src/BasicButton.vue                   |   12 
 src/components/Container/src/typing.ts                      |    0 
 src/components/Form/src/components/FormAction.vue           |   20 
 src/components/Container/index.ts                           |   14 
 src/components/Basic/src/BasicHelp.vue                      |  108 ++---
 src/components/Container/src/ScrollContainer.vue            |    9 
 src/components/Application/src/search/AppSearchModal.vue    |   21 
 src/components/Authority/index.ts                           |    5 
 src/components/Application/src/search/useMenuSearch.ts      |   31 +
 src/components/CodeEditor/src/json-preview/JsonPreview.vue  |    8 
 src/components/Application/src/useAppContext.ts             |    1 
 src/components/CodeEditor/src/codemirror/CodeMirror.vue     |   36 -
 src/components/Container/src/LazyContainer.vue              |   66 ++-
 src/components/Application/src/search/AppSearchFooter.vue   |   15 
 src/components/Application/src/AppDarkModeToggle.vue        |   28 
 src/utils/index.ts                                          |   13 
 /dev/null                                                   |   12 
 src/components/Basic/index.ts                               |   11 
 src/components/CodeEditor/index.ts                          |    6 
 yarn.lock                                                   |  169 ++++----
 package.json                                                |   16 
 src/components/FlowChart/index.ts                           |    4 
 src/components/Basic/src/BasicTitle.vue                     |   37 +
 src/views/sys/login/Login.vue                               |    3 
 src/components/Application/src/AppLocalePicker.vue          |   37 +
 src/components/Application/src/AppProvider.vue              |   22 
 src/components/Button/index.ts                              |    8 
 40 files changed, 533 insertions(+), 527 deletions(-)

diff --git a/package.json b/package.json
index e395a4c..b2c36f4 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
     "@iconify/iconify": "^2.0.1",
     "@logicflow/core": "^0.4.11",
     "@logicflow/extension": "^0.4.12",
-    "@vueuse/core": "^4.11.2",
+    "@vueuse/core": "^5.0.1",
     "@zxcvbn-ts/core": "^0.3.0",
     "ant-design-vue": "2.1.2",
     "axios": "^0.21.1",
@@ -63,7 +63,7 @@
   "devDependencies": {
     "@commitlint/cli": "^12.1.4",
     "@commitlint/config-conventional": "^12.1.4",
-    "@iconify/json": "^1.1.353",
+    "@iconify/json": "^1.1.354",
     "@purge-icons/generated": "^0.7.0",
     "@types/codemirror": "^5.60.0",
     "@types/crypto-js": "^4.0.1",
@@ -71,13 +71,13 @@
     "@types/inquirer": "^7.3.1",
     "@types/lodash-es": "^4.17.4",
     "@types/mockjs": "^1.0.3",
-    "@types/node": "^15.12.1",
+    "@types/node": "^15.12.2",
     "@types/nprogress": "^0.2.0",
     "@types/qrcode": "^1.4.0",
     "@types/qs": "^6.9.6",
     "@types/sortablejs": "^1.10.6",
-    "@typescript-eslint/eslint-plugin": "^4.26.0",
-    "@typescript-eslint/parser": "^4.26.0",
+    "@typescript-eslint/eslint-plugin": "^4.26.1",
+    "@typescript-eslint/parser": "^4.26.1",
     "@vitejs/plugin-legacy": "^1.4.1",
     "@vitejs/plugin-vue": "^1.2.3",
     "@vitejs/plugin-vue-jsx": "^1.1.5",
@@ -92,7 +92,7 @@
     "eslint-define-config": "^1.0.8",
     "eslint-plugin-prettier": "^3.4.0",
     "eslint-plugin-vue": "^7.10.0",
-    "esno": "^0.7.0",
+    "esno": "^0.7.1",
     "fs-extra": "^10.0.0",
     "http-server": "^0.12.3",
     "husky": "^6.0.0",
@@ -121,14 +121,14 @@
     "vite-plugin-style-import": "^0.10.1",
     "vite-plugin-svg-icons": "^0.7.0",
     "vite-plugin-theme": "^0.8.1",
-    "vite-plugin-windicss": "^1.0.1",
+    "vite-plugin-windicss": "^1.0.2",
     "vue-eslint-parser": "^7.6.0",
     "vue-tsc": "^0.1.7"
   },
   "resolutions": {
     "//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
     "bin-wrapper": "npm:bin-wrapper-china",
-    "rollup": "^2.51.0"
+    "rollup": "^2.51.1"
   },
   "repository": {
     "type": "git",
diff --git a/src/components/Application/index.ts b/src/components/Application/index.ts
index c1b8fb8..d7c5133 100644
--- a/src/components/Application/index.ts
+++ b/src/components/Application/index.ts
@@ -1,8 +1,15 @@
-import AppLogo from './src/AppLogo.vue';
-import AppProvider from './src/AppProvider.vue';
-import AppSearch from './src/search/AppSearch.vue';
-import AppLocalePicker from './src/AppLocalePicker.vue';
-import AppDarkModeToggle from './src/AppDarkModeToggle.vue';
+import { withInstall } from '/@/utils';
+
+import appLogo from './src/AppLogo.vue';
+import appProvider from './src/AppProvider.vue';
+import appSearch from './src/search/AppSearch.vue';
+import appLocalePicker from './src/AppLocalePicker.vue';
+import appDarkModeToggle from './src/AppDarkModeToggle.vue';
 
 export { useAppProviderContext } from './src/useAppContext';
-export { AppLogo, AppProvider, AppSearch, AppLocalePicker, AppDarkModeToggle };
+
+export const AppLogo = withInstall(appLogo);
+export const AppProvider = withInstall(appProvider);
+export const AppSearch = withInstall(appSearch);
+export const AppLocalePicker = withInstall(appLocalePicker);
+export const AppDarkModeToggle = withInstall(appDarkModeToggle);
diff --git a/src/components/Application/src/AppDarkModeToggle.vue b/src/components/Application/src/AppDarkModeToggle.vue
index 9363c1a..bfc7dfb 100644
--- a/src/components/Application/src/AppDarkModeToggle.vue
+++ b/src/components/Application/src/AppDarkModeToggle.vue
@@ -1,14 +1,5 @@
 <template>
-  <div
-    v-if="getShowDarkModeToggle"
-    :class="[
-      prefixCls,
-      {
-        [`${prefixCls}--dark`]: isDark,
-      },
-    ]"
-    @click="toggleDarkMode"
-  >
+  <div v-if="getShowDarkModeToggle" :class="getClass" @click="toggleDarkMode">
     <div :class="`${prefixCls}-inner`"> </div>
     <SvgIcon size="14" name="sun" />
     <SvgIcon size="14" name="moon" />
@@ -16,24 +7,28 @@
 </template>
 <script lang="ts">
   import { defineComponent, computed } from 'vue';
-
-  import { useDesign } from '/@/hooks/web/useDesign';
-
   import { SvgIcon } from '/@/components/Icon';
+  import { useDesign } from '/@/hooks/web/useDesign';
   import { useRootSetting } from '/@/hooks/setting/useRootSetting';
   import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
   import { updateDarkTheme } from '/@/logics/theme/dark';
-
   import { ThemeEnum } from '/@/enums/appEnum';
 
   export default defineComponent({
     name: 'DarkModeToggle',
     components: { SvgIcon },
     setup() {
-      const { prefixCls } = useDesign('dark-mode-toggle');
+      const { prefixCls } = useDesign('dark-switch');
       const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
 
       const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
+
+      const getClass = computed(() => [
+        prefixCls,
+        {
+          [`${prefixCls}--dark`]: isDark,
+        },
+      ]);
 
       function toggleDarkMode() {
         const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
@@ -44,6 +39,7 @@
       }
 
       return {
+        getClass,
         isDark,
         prefixCls,
         toggleDarkMode,
@@ -53,7 +49,7 @@
   });
 </script>
 <style lang="less" scoped>
-  @prefix-cls: ~'@{namespace}-dark-mode-toggle';
+  @prefix-cls: ~'@{namespace}-dark-switch';
 
   html[data-theme='dark'] {
     .@{prefix-cls} {
diff --git a/src/components/Application/src/AppLocalePicker.vue b/src/components/Application/src/AppLocalePicker.vue
index 9f19b07..ca8b55c 100644
--- a/src/components/Application/src/AppLocalePicker.vue
+++ b/src/components/Application/src/AppLocalePicker.vue
@@ -13,39 +13,44 @@
   >
     <span class="cursor-pointer flex items-center">
       <Icon icon="ion:language" />
-      <span v-if="showText" class="ml-1">{{ getLangText }}</span>
+      <span v-if="showText" class="ml-1">{{ getLocaleText }}</span>
     </span>
   </Dropdown>
 </template>
 <script lang="ts">
   import type { LocaleType } from '/#/config';
   import type { DropMenu } from '/@/components/Dropdown';
-
   import { defineComponent, ref, watchEffect, unref, computed } from 'vue';
   import { Dropdown } from '/@/components/Dropdown';
-  import Icon from '/@/components/Icon';
-
+  import { Icon } from '/@/components/Icon';
   import { useLocale } from '/@/locales/useLocale';
   import { localeList } from '/@/settings/localeSetting';
-  import { propTypes } from '/@/utils/propTypes';
+
+  const props = {
+    /**
+     * Whether to display text
+     */
+    showText: { type: Boolean, default: true },
+    /**
+     * Whether to refresh the interface when changing
+     */
+    reload: { type: Boolean },
+  };
 
   export default defineComponent({
     name: 'AppLocalPicker',
     components: { Dropdown, Icon },
-    props: {
-      // Whether to display text
-      showText: propTypes.bool.def(true),
-      // Whether to refresh the interface when changing
-      reload: propTypes.bool,
-    },
+    props,
     setup(props) {
       const selectedKeys = ref<string[]>([]);
 
       const { changeLocale, getLocale } = useLocale();
 
-      const getLangText = computed(() => {
+      const getLocaleText = computed(() => {
         const key = selectedKeys.value[0];
-        if (!key) return '';
+        if (!key) {
+          return '';
+        }
         return localeList.find((item) => item.event === key)?.text;
       });
 
@@ -60,11 +65,13 @@
       }
 
       function handleMenuEvent(menu: DropMenu) {
-        if (unref(getLocale) === menu.event) return;
+        if (unref(getLocale) === menu.event) {
+          return;
+        }
         toggleLocale(menu.event as string);
       }
 
-      return { localeList, handleMenuEvent, selectedKeys, getLangText };
+      return { localeList, handleMenuEvent, selectedKeys, getLocaleText };
     },
   });
 </script>
diff --git a/src/components/Application/src/AppLogo.vue b/src/components/Application/src/AppLogo.vue
index 413fe04..927000e 100644
--- a/src/components/Application/src/AppLogo.vue
+++ b/src/components/Application/src/AppLogo.vue
@@ -3,63 +3,69 @@
  * @Description: logo component
 -->
 <template>
-  <div
-    class="anticon"
-    :class="[prefixCls, theme, { 'collapsed-show-title': getCollapsedShowTitle }]"
-    @click="handleGoHome"
-  >
+  <div class="anticon" :class="getAppLogoClass" @click="goHome">
     <img src="../../../assets/images/logo.png" />
-    <div
-      class="ml-2 truncate md:opacity-100"
-      :class="[
-        `${prefixCls}__title`,
-        {
-          'xs:opacity-0': !alwaysShowTitle,
-        },
-      ]"
-      v-show="showTitle"
-    >
+    <div class="ml-2 truncate md:opacity-100" :class="getTitleClass" v-show="showTitle">
       {{ title }}
     </div>
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
-
+  import { defineComponent, computed, unref } from 'vue';
   import { useGlobSetting } from '/@/hooks/setting';
   import { useGo } from '/@/hooks/web/usePage';
   import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
   import { useDesign } from '/@/hooks/web/useDesign';
-
   import { PageEnum } from '/@/enums/pageEnum';
-  import { propTypes } from '/@/utils/propTypes';
+
+  const props = {
+    /**
+     * The theme of the current parent component
+     */
+    theme: { type: String, validator: (v) => ['light', 'dark'].includes(v) },
+    /**
+     * Whether to show title
+     */
+    showTitle: { type: Boolean, default: true },
+    /**
+     * The title is also displayed when the menu is collapsed
+     */
+    alwaysShowTitle: { type: Boolean },
+  };
 
   export default defineComponent({
     name: 'AppLogo',
-    props: {
-      /**
-       * The theme of the current parent component
-       */
-      theme: propTypes.oneOf(['light', 'dark']),
-      // Whether to show title
-      showTitle: propTypes.bool.def(true),
-      alwaysShowTitle: propTypes.bool.def(false),
-    },
-    setup() {
+    props: props,
+    setup(props) {
       const { prefixCls } = useDesign('app-logo');
       const { getCollapsedShowTitle } = useMenuSetting();
       const { title } = useGlobSetting();
       const go = useGo();
 
-      function handleGoHome(): void {
+      const getAppLogoClass = computed(() => [
+        prefixCls,
+        props.theme,
+        { 'collapsed-show-title': unref(getCollapsedShowTitle) },
+      ]);
+
+      const getTitleClass = computed(() => [
+        `${prefixCls}__title`,
+        {
+          'xs:opacity-0': !props.alwaysShowTitle,
+        },
+      ]);
+
+      function goHome() {
         go(PageEnum.BASE_HOME);
       }
 
       return {
-        handleGoHome,
+        getAppLogoClass,
+        getTitleClass,
+        getCollapsedShowTitle,
+        goHome,
         title,
         prefixCls,
-        getCollapsedShowTitle,
       };
     },
   });
diff --git a/src/components/Application/src/AppProvider.vue b/src/components/Application/src/AppProvider.vue
index d0722bf..fe19a80 100644
--- a/src/components/Application/src/AppProvider.vue
+++ b/src/components/Application/src/AppProvider.vue
@@ -1,26 +1,29 @@
 <script lang="ts">
   import { defineComponent, toRefs, ref, unref } from 'vue';
-
   import { createAppProviderContext } from './useAppContext';
-
-  import { prefixCls } from '/@/settings/designSetting';
   import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
-  import { propTypes } from '/@/utils/propTypes';
+  import { prefixCls } from '/@/settings/designSetting';
   import { useAppStore } from '/@/store/modules/app';
   import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
+
+  const props = {
+    /**
+     * class style prefix
+     */
+    prefixCls: { type: String, default: prefixCls },
+  };
 
   export default defineComponent({
     name: 'AppProvider',
     inheritAttrs: false,
-    props: {
-      prefixCls: propTypes.string.def(prefixCls),
-    },
+    props,
     setup(props, { slots }) {
       const isMobile = ref(false);
       const isSetState = ref(false);
 
       const appStore = useAppStore();
 
+      // Monitor screen breakpoint information changes
       createBreakpointListen(({ screenMap, sizeEnum, width }) => {
         const lgWidth = screenMap.get(sizeEnum.LG);
         if (lgWidth) {
@@ -30,8 +33,13 @@
       });
 
       const { prefixCls } = toRefs(props);
+
+      // Inject variables into the global
       createAppProviderContext({ prefixCls, isMobile });
 
+      /**
+       * Used to maintain the state before the window changes
+       */
       function handleRestoreState() {
         if (unref(isMobile)) {
           if (!unref(isSetState)) {
diff --git a/src/components/Application/src/search/AppSearch.vue b/src/components/Application/src/search/AppSearch.vue
index 73d822e..63d346e 100644
--- a/src/components/Application/src/search/AppSearch.vue
+++ b/src/components/Application/src/search/AppSearch.vue
@@ -4,11 +4,11 @@
   import { SearchOutlined } from '@ant-design/icons-vue';
   import AppSearchModal from './AppSearchModal.vue';
   import { useI18n } from '/@/hooks/web/useI18n';
+
   export default defineComponent({
     name: 'AppSearch',
     setup() {
       const showModal = ref(false);
-
       const { t } = useI18n();
 
       function changeModal(show: boolean) {
diff --git a/src/components/Application/src/search/AppSearchFooter.vue b/src/components/Application/src/search/AppSearchFooter.vue
index 12e7ff6..d7076aa 100644
--- a/src/components/Application/src/search/AppSearchFooter.vue
+++ b/src/components/Application/src/search/AppSearchFooter.vue
@@ -1,11 +1,11 @@
 <template>
   <div :class="`${prefixCls}`">
-    <AppSearchKeyItem :class="`${prefixCls}__item`" icon="ant-design:enter-outlined" />
+    <AppSearchKeyItem :class="`${prefixCls}-item`" icon="ant-design:enter-outlined" />
     <span>{{ t('component.app.toSearch') }}</span>
-    <AppSearchKeyItem :class="`${prefixCls}__item`" icon="ion:arrow-up-outline" />
-    <AppSearchKeyItem :class="`${prefixCls}__item`" icon="ion:arrow-down-outline" />
+    <AppSearchKeyItem :class="`${prefixCls}-item`" icon="ion:arrow-up-outline" />
+    <AppSearchKeyItem :class="`${prefixCls}-item`" icon="ion:arrow-down-outline" />
     <span>{{ t('component.app.toNavigate') }}</span>
-    <AppSearchKeyItem :class="`${prefixCls}__item`" icon="mdi:keyboard-esc" />
+    <AppSearchKeyItem :class="`${prefixCls}-item`" icon="mdi:keyboard-esc" />
     <span>{{ t('common.closeText') }}</span>
   </div>
 </template>
@@ -21,10 +21,7 @@
     setup() {
       const { prefixCls } = useDesign('app-search-footer');
       const { t } = useI18n();
-      return {
-        prefixCls,
-        t,
-      };
+      return { prefixCls, t };
     },
   });
 </script>
@@ -44,7 +41,7 @@
     align-items: center;
     flex-shrink: 0;
 
-    &__item {
+    &-item {
       display: flex;
       width: 20px;
       height: 18px;
diff --git a/src/components/Application/src/search/AppSearchKeyItem.vue b/src/components/Application/src/search/AppSearchKeyItem.vue
index d24b43f..b535cef 100644
--- a/src/components/Application/src/search/AppSearchKeyItem.vue
+++ b/src/components/Application/src/search/AppSearchKeyItem.vue
@@ -8,8 +8,6 @@
   import { Icon } from '/@/components/Icon';
   export default defineComponent({
     components: { Icon },
-    props: {
-      icon: String,
-    },
+    props: { icon: String },
   });
 </script>
diff --git a/src/components/Application/src/search/AppSearchModal.vue b/src/components/Application/src/search/AppSearchModal.vue
index 2e722c3..f4be101 100644
--- a/src/components/Application/src/search/AppSearchModal.vue
+++ b/src/components/Application/src/search/AppSearchModal.vue
@@ -12,7 +12,6 @@
               @change="handleSearch"
             >
               <template #prefix>
-                <!-- <Icon icon="ion:search"/> -->
                 <SearchOutlined />
               </template>
             </Input>
@@ -59,21 +58,20 @@
 </template>
 <script lang="ts">
   import { defineComponent, computed, unref, ref, watch, nextTick } from 'vue';
-
   import { SearchOutlined } from '@ant-design/icons-vue';
   import { Input } from 'ant-design-vue';
   import AppSearchFooter from './AppSearchFooter.vue';
   import Icon from '/@/components/Icon';
-
   import clickOutside from '/@/directives/clickOutside';
-
   import { useDesign } from '/@/hooks/web/useDesign';
   import { useRefs } from '/@/hooks/core/useRefs';
   import { useMenuSearch } from './useMenuSearch';
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useAppInject } from '/@/hooks/web/useAppInject';
 
-  import { propTypes } from '/@/utils/propTypes';
+  const props = {
+    visible: { type: Boolean },
+  };
 
   export default defineComponent({
     name: 'AppSearchModal',
@@ -81,17 +79,16 @@
     directives: {
       clickOutside,
     },
-    props: {
-      visible: propTypes.bool,
-    },
+    props,
     emits: ['close'],
     setup(props, { emit }) {
       const scrollWrap = ref<ElRef>(null);
-      const { prefixCls } = useDesign('app-search-modal');
+      const inputRef = ref<Nullable<HTMLElement>>(null);
+
       const { t } = useI18n();
+      const { prefixCls } = useDesign('app-search-modal');
       const [refs, setRefs] = useRefs();
       const { getIsMobile } = useAppInject();
-      const inputRef = ref<Nullable<HTMLElement>>(null);
 
       const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =
         useMenuSearch(refs, scrollWrap, emit);
@@ -109,8 +106,8 @@
 
       watch(
         () => props.visible,
-        (v: boolean) => {
-          v &&
+        (visible: boolean) => {
+          visible &&
             nextTick(() => {
               unref(inputRef)?.focus();
             });
diff --git a/src/components/Application/src/search/useMenuSearch.ts b/src/components/Application/src/search/useMenuSearch.ts
index 0bfd7b6..df6f395 100644
--- a/src/components/Application/src/search/useMenuSearch.ts
+++ b/src/components/Application/src/search/useMenuSearch.ts
@@ -1,12 +1,8 @@
 import type { Menu } from '/@/router/types';
-
 import { ref, onBeforeMount, unref, Ref, nextTick } from 'vue';
-
 import { getMenus } from '/@/router/menus';
-
 import { cloneDeep } from 'lodash-es';
 import { filter, forEach } from '/@/utils/helper/treeHelper';
-
 import { useGo } from '/@/hooks/web/usePage';
 import { useScrollTo } from '/@/hooks/event/useScrollTo';
 import { onKeyStroke, useDebounceFn } from '@vueuse/core';
@@ -67,7 +63,6 @@
 
   function handlerSearchResult(filterMenu: Menu[], reg: RegExp, parent?: Menu) {
     const ret: SearchResult[] = [];
-
     filterMenu.forEach((item) => {
       const { name, path, icon, children } = item;
       if (reg.test(name) && !children?.length) {
@@ -84,11 +79,13 @@
     return ret;
   }
 
+  // Activate when the mouse moves to a certain line
   function handleMouseenter(e: any) {
     const index = e.target.dataset.index;
     activeIndex.value = Number(index);
   }
 
+  // Arrow key up
   function handleUp() {
     if (!searchResult.value.length) return;
     activeIndex.value--;
@@ -98,6 +95,7 @@
     handleScroll();
   }
 
+  // Arrow key down
   function handleDown() {
     if (!searchResult.value.length) return;
     activeIndex.value++;
@@ -107,15 +105,23 @@
     handleScroll();
   }
 
+  // When the keyboard up and down keys move to an invisible place
+  // the scroll bar needs to scroll automatically
   function handleScroll() {
     const refList = unref(refs);
-    if (!refList || !Array.isArray(refList) || refList.length === 0 || !unref(scrollWrap)) return;
+    if (!refList || !Array.isArray(refList) || refList.length === 0 || !unref(scrollWrap)) {
+      return;
+    }
 
     const index = unref(activeIndex);
     const currentRef = refList[index];
-    if (!currentRef) return;
+    if (!currentRef) {
+      return;
+    }
     const wrapEl = unref(scrollWrap);
-    if (!wrapEl) return;
+    if (!wrapEl) {
+      return;
+    }
     const scrollHeight = currentRef.offsetTop + currentRef.offsetHeight;
     const wrapHeight = wrapEl.offsetHeight;
     const { start } = useScrollTo({
@@ -126,8 +132,11 @@
     start();
   }
 
+  // enter keyboard event
   async function handleEnter() {
-    if (!searchResult.value.length) return;
+    if (!searchResult.value.length) {
+      return;
+    }
     const result = unref(searchResult);
     const index = unref(activeIndex);
     if (result.length === 0 || index < 0) {
@@ -139,14 +148,18 @@
     go(to.path);
   }
 
+  // close search modal
   function handleClose() {
     searchResult.value = [];
     emit('close');
   }
 
+  // enter search
   onKeyStroke('Enter', handleEnter);
+  // Monitor keyboard arrow keys
   onKeyStroke('ArrowUp', handleUp);
   onKeyStroke('ArrowDown', handleDown);
+  // esc close
   onKeyStroke('Escape', handleClose);
 
   return { handleSearch, searchResult, keyword, activeIndex, handleMouseenter, handleEnter };
diff --git a/src/components/Application/src/useAppContext.ts b/src/components/Application/src/useAppContext.ts
index f3bacd1..8bdfb4f 100644
--- a/src/components/Application/src/useAppContext.ts
+++ b/src/components/Application/src/useAppContext.ts
@@ -3,7 +3,6 @@
 
 export interface AppProviderContextProps {
   prefixCls: Ref<string>;
-
   isMobile: Ref<boolean>;
 }
 
diff --git a/src/components/Authority/index.ts b/src/components/Authority/index.ts
index 27ae1e9..2f0eab7 100644
--- a/src/components/Authority/index.ts
+++ b/src/components/Authority/index.ts
@@ -1,3 +1,4 @@
-import Authority from './src/Authority.vue';
+import { withInstall } from '/@/utils';
+import authority from './src/Authority.vue';
 
-export { Authority };
+export const Authority = withInstall(authority);
diff --git a/src/components/Authority/src/Authority.vue b/src/components/Authority/src/Authority.vue
index 8e0c272..0d35938 100644
--- a/src/components/Authority/src/Authority.vue
+++ b/src/components/Authority/src/Authority.vue
@@ -4,11 +4,8 @@
 <script lang="ts">
   import type { PropType } from 'vue';
   import { defineComponent } from 'vue';
-
   import { RoleEnum } from '/@/enums/roleEnum';
-
   import { usePermission } from '/@/hooks/web/usePermission';
-
   import { getSlot } from '/@/utils/helper/tsxHelper';
 
   export default defineComponent({
diff --git a/src/components/Basic/index.ts b/src/components/Basic/index.ts
index 5a0845d..97a53a1 100644
--- a/src/components/Basic/index.ts
+++ b/src/components/Basic/index.ts
@@ -1,5 +1,8 @@
-import BasicArrow from './src/BasicArrow.vue';
-import BasicTitle from './src/BasicTitle.vue';
-import BasicHelp from './src/BasicHelp.vue';
+import { withInstall } from '/@/utils';
+import basicArrow from './src/BasicArrow.vue';
+import basicTitle from './src/BasicTitle.vue';
+import basicHelp from './src/BasicHelp.vue';
 
-export { BasicArrow, BasicTitle, BasicHelp };
+export const BasicArrow = withInstall(basicArrow);
+export const BasicTitle = withInstall(basicTitle);
+export const BasicHelp = withInstall(basicHelp);
diff --git a/src/components/Basic/src/BasicArrow.vue b/src/components/Basic/src/BasicArrow.vue
index a0cd3b0..e1f40f3 100644
--- a/src/components/Basic/src/BasicArrow.vue
+++ b/src/components/Basic/src/BasicArrow.vue
@@ -9,41 +9,50 @@
 </template>
 <script lang="ts">
   import { defineComponent, computed } from 'vue';
-
+  import { Icon } from '/@/components/Icon';
   import { useDesign } from '/@/hooks/web/useDesign';
 
-  import { propTypes } from '/@/utils/propTypes';
-
-  import { Icon } from '/@/components/Icon';
+  const props = {
+    /**
+     * Arrow expand state
+     */
+    expand: { type: Boolean },
+    /**
+     * Arrow up by default
+     */
+    up: { type: Boolean },
+    /**
+     * Arrow down by default
+     */
+    down: { type: Boolean },
+    /**
+     * Cancel padding/margin for inline
+     */
+    inset: { type: Boolean },
+  };
 
   export default defineComponent({
     name: 'BasicArrow',
     components: { Icon },
-    props: {
-      expand: propTypes.bool,
-      top: propTypes.bool,
-      bottom: propTypes.bool,
-      inset: propTypes.bool,
-    },
+    props,
     setup(props) {
       const { prefixCls } = useDesign('basic-arrow');
 
+      // get component class
       const getClass = computed(() => {
-        const { expand, top, bottom, inset } = props;
+        const { expand, up, down, inset } = props;
         return [
           prefixCls,
           {
             [`${prefixCls}--active`]: expand,
-            top,
+            up,
             inset,
-            bottom,
+            down,
           },
         ];
       });
 
-      return {
-        getClass,
-      };
+      return { getClass };
     },
   });
 </script>
@@ -65,19 +74,19 @@
       line-height: 0px;
     }
 
-    &.top {
+    &.up {
       transform: rotate(-90deg);
     }
 
-    &.bottom {
+    &.down {
       transform: rotate(90deg);
     }
 
-    &.top.@{prefix-cls}--active {
+    &.up.@{prefix-cls}--active {
       transform: rotate(90deg);
     }
 
-    &.bottom.@{prefix-cls}--active {
+    &.down.@{prefix-cls}--active {
       transform: rotate(-90deg);
     }
   }
diff --git a/src/components/Basic/src/BasicHelp.vue b/src/components/Basic/src/BasicHelp.vue
index 4657822..0a3cc16 100644
--- a/src/components/Basic/src/BasicHelp.vue
+++ b/src/components/Basic/src/BasicHelp.vue
@@ -1,104 +1,90 @@
 <script lang="tsx">
   import type { CSSProperties, PropType } from 'vue';
   import { defineComponent, computed, unref } from 'vue';
-
   import { Tooltip } from 'ant-design-vue';
   import { InfoCircleOutlined } from '@ant-design/icons-vue';
-
   import { getPopupContainer } from '/@/utils';
   import { isString, isArray } from '/@/utils/is';
   import { getSlot } from '/@/utils/helper/tsxHelper';
-  import { propTypes } from '/@/utils/propTypes';
-
   import { useDesign } from '/@/hooks/web/useDesign';
+
+  const props = {
+    /**
+     * Help text max-width
+     * @default: 600px
+     */
+    maxWidth: { type: String, default: '600px' },
+    /**
+     * Whether to display the serial number
+     * @default: false
+     */
+    showIndex: { type: Boolean },
+    /**
+     * Help text font color
+     * @default: #ffffff
+     */
+    color: { type: String, default: '#ffffff' },
+    /**
+     * Help text font size
+     * @default: 14px
+     */
+    fontSize: { type: String, default: '14px' },
+    /**
+     * Help text list
+     */
+    placement: { type: String, default: 'right' },
+    /**
+     * Help text list
+     */
+    text: { type: [Array, String] as PropType<string[] | string> },
+  };
 
   export default defineComponent({
     name: 'BasicHelp',
     components: { Tooltip },
-    props: {
-      // max-width
-      maxWidth: propTypes.string.def('600px'),
-      // Whether to display the serial number
-      showIndex: propTypes.bool,
-      // color
-      color: propTypes.string.def('#ffffff'),
-      fontSize: propTypes.string.def('14px'),
-      placement: propTypes.string.def('right'),
-      absolute: propTypes.bool,
-      // Text list
-      text: {
-        type: [Array, String] as PropType<string[] | string>,
-      },
-      // 瀹氫綅
-      position: {
-        type: [Object] as PropType<any>,
-        default: () => ({
-          position: 'absolute',
-          left: 0,
-          bottom: 0,
-        }),
-      },
-    },
+    props,
     setup(props, { slots }) {
       const { prefixCls } = useDesign('basic-help');
 
-      const getOverlayStyle = computed(
-        (): CSSProperties => {
-          return {
-            maxWidth: props.maxWidth,
-          };
-        }
+      const getTooltipStyle = computed(
+        (): CSSProperties => ({ color: props.color, fontSize: props.fontSize })
       );
 
-      const getWrapStyle = computed(
-        (): CSSProperties => {
-          return {
-            color: props.color,
-            fontSize: props.fontSize,
-          };
-        }
-      );
+      const getOverlayStyle = computed((): CSSProperties => ({ maxWidth: props.maxWidth }));
 
-      const getMainStyleRef = computed(() => {
-        return props.absolute ? props.position : {};
-      });
+      function renderTitle() {
+        const textList = props.text;
 
-      const renderTitle = () => {
-        const list = props.text;
-
-        if (isString(list)) {
-          return <p>{list}</p>;
+        if (isString(textList)) {
+          return <p>{textList}</p>;
         }
 
-        if (isArray(list)) {
-          return list.map((item, index) => {
+        if (isArray(textList)) {
+          return textList.map((text, index) => {
             return (
-              <p key={item}>
+              <p key={text}>
                 <>
                   {props.showIndex ? `${index + 1}. ` : ''}
-                  {item}
+                  {text}
                 </>
               </p>
             );
           });
         }
-
         return null;
-      };
+      }
 
       return () => {
         return (
           <Tooltip
-            title={<div style={unref(getWrapStyle)}>{renderTitle()}</div>}
             overlayClassName={`${prefixCls}__wrap`}
+            title={<div style={unref(getTooltipStyle)}>{renderTitle()}</div>}
             autoAdjustOverflow={true}
             overlayStyle={unref(getOverlayStyle)}
-            placement={props.placement as 'left'}
+            placement={props.placement as 'right'}
             getPopupContainer={() => getPopupContainer()}
           >
-            <span class={prefixCls} style={unref(getMainStyleRef)}>
-              {getSlot(slots) || <InfoCircleOutlined />}
-            </span>
+            <span class={prefixCls}>{getSlot(slots) || <InfoCircleOutlined />}</span>
           </Tooltip>
         );
       };
diff --git a/src/components/Basic/src/BasicTitle.vue b/src/components/Basic/src/BasicTitle.vue
index 64e1b7b..9b5b287 100644
--- a/src/components/Basic/src/BasicTitle.vue
+++ b/src/components/Basic/src/BasicTitle.vue
@@ -1,30 +1,40 @@
 <template>
   <span :class="getClass">
     <slot></slot>
-    <BasicHelp :class="`${prefixCls}__help`" v-if="helpMessage" :text="helpMessage" />
+    <BasicHelp :class="`${prefixCls}-help`" v-if="helpMessage" :text="helpMessage" />
   </span>
 </template>
 <script lang="ts">
   import type { PropType } from 'vue';
-
   import { defineComponent, computed } from 'vue';
   import BasicHelp from './BasicHelp.vue';
-
   import { useDesign } from '/@/hooks/web/useDesign';
 
-  import { propTypes } from '/@/utils/propTypes';
+  const props = {
+    /**
+     * Help text list or string
+     * @default: ''
+     */
+    helpMessage: {
+      type: [String, Array] as PropType<string | string[]>,
+      default: '',
+    },
+    /**
+     * Whether the color block on the left side of the title
+     * @default: false
+     */
+    span: { type: Boolean },
+    /**
+     * Whether to default the text, that is, not bold
+     * @default: false
+     */
+    normal: { type: Boolean },
+  };
 
   export default defineComponent({
     name: 'BasicTitle',
     components: { BasicHelp },
-    props: {
-      helpMessage: {
-        type: [String, Array] as PropType<string | string[]>,
-        default: '',
-      },
-      span: propTypes.bool,
-      normal: propTypes.bool.def(false),
-    },
+    props,
     setup(props, { slots }) {
       const { prefixCls } = useDesign('basic-title');
 
@@ -33,6 +43,7 @@
         { [`${prefixCls}-show-span`]: props.span && slots.default },
         { [`${prefixCls}-normal`]: props.normal },
       ]);
+
       return { prefixCls, getClass };
     },
   });
@@ -67,7 +78,7 @@
       content: '';
     }
 
-    &__help {
+    &-help {
       margin-left: 10px;
     }
   }
diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts
index 1a229cf..a367faf 100644
--- a/src/components/Button/index.ts
+++ b/src/components/Button/index.ts
@@ -1,4 +1,6 @@
-import Button from './src/BasicButton.vue';
-import PopConfirmButton from './src/PopConfirmButton.vue';
+import { withInstall } from '/@/utils';
+import button from './src/BasicButton.vue';
+import popConfirmButton from './src/PopConfirmButton.vue';
 
-export { Button, PopConfirmButton };
+export const Button = withInstall(button);
+export const PopConfirmButton = withInstall(popConfirmButton);
diff --git a/src/components/Button/src/BasicButton.vue b/src/components/Button/src/BasicButton.vue
index d4fadbc..c043ab7 100644
--- a/src/components/Button/src/BasicButton.vue
+++ b/src/components/Button/src/BasicButton.vue
@@ -13,11 +13,21 @@
   import { Icon } from '/@/components/Icon';
 
   const props = {
-    color: { type: String, validate: (v) => ['error', 'warning', 'success', ''].includes(v) },
+    color: { type: String, validator: (v) => ['error', 'warning', 'success', ''].includes(v) },
     loading: { type: Boolean },
     disabled: { type: Boolean },
+    /**
+     * Text before icon.
+     */
     preIcon: { type: String },
+    /**
+     * Text after icon.
+     */
     postIcon: { type: String },
+    /**
+     * preIcon and postIcon icon size.
+     * @default: 14
+     */
     iconSize: { type: Number, default: 14 },
     onClick: { type: Function as PropType<(...args) => any>, default: null },
   };
diff --git a/src/components/Button/src/PopConfirmButton.vue b/src/components/Button/src/PopConfirmButton.vue
index 4e546a0..4c110fa 100644
--- a/src/components/Button/src/PopConfirmButton.vue
+++ b/src/components/Button/src/PopConfirmButton.vue
@@ -1,7 +1,7 @@
 <script lang="ts">
   import { defineComponent, h, unref, computed } from 'vue';
-  import { Popconfirm } from 'ant-design-vue';
   import BasicButton from './BasicButton.vue';
+  import { Popconfirm } from 'ant-design-vue';
   import { extendSlots } from '/@/utils/helper/tsxHelper';
   import { omit } from 'lodash-es';
   import { useAttrs } from '/@/hooks/core/useAttrs';
diff --git a/src/components/ClickOutSide/index.ts b/src/components/ClickOutSide/index.ts
index 031c943..5e7dd2d 100644
--- a/src/components/ClickOutSide/index.ts
+++ b/src/components/ClickOutSide/index.ts
@@ -1,3 +1,4 @@
-import ClickOutSide from './src/ClickOutSide.vue';
+import { withInstall } from '/@/utils';
+import clickOutSide from './src/ClickOutSide.vue';
 
-export { ClickOutSide };
+export const ClickOutSide = withInstall(clickOutSide);
diff --git a/src/components/CodeEditor/index.ts b/src/components/CodeEditor/index.ts
index faefea5..a9b0c30 100644
--- a/src/components/CodeEditor/index.ts
+++ b/src/components/CodeEditor/index.ts
@@ -1,6 +1,6 @@
-import { install } from '/@/utils/install';
+import { withInstall } from '/@/utils';
 import codeEditor from './src/CodeEditor.vue';
 import jsonPreview from './src/json-preview/JsonPreview.vue';
 
-export const CodeEditor = install(codeEditor);
-export const JsonPreview = install(jsonPreview);
+export const CodeEditor = withInstall(codeEditor);
+export const JsonPreview = withInstall(jsonPreview);
diff --git a/src/components/CodeEditor/src/CodeEditor.vue b/src/components/CodeEditor/src/CodeEditor.vue
index c9e8428..5e9d32c 100644
--- a/src/components/CodeEditor/src/CodeEditor.vue
+++ b/src/components/CodeEditor/src/CodeEditor.vue
@@ -1,6 +1,11 @@
 <template>
   <div class="h-full">
-    <CodeMirrorEditor :value="getValue" @change="handleValueChange" :mode="mode" :readonly="readonly" />
+    <CodeMirrorEditor
+      :value="getValue"
+      @change="handleValueChange"
+      :mode="mode"
+      :readonly="readonly"
+    />
   </div>
 </template>
 <script lang="ts">
@@ -13,43 +18,34 @@
     html: 'htmlmixed',
     js: 'javascript',
   };
+
+  const props = {
+    value: { type: [Object, String] as PropType<Record<string, any> | string> },
+    mode: { type: String, default: MODE.JSON },
+    readonly: { type: Boolean },
+  };
+
   export default defineComponent({
     name: 'CodeEditor',
     components: { CodeMirrorEditor },
-    props: {
-      value: {
-        type: [Object, String],
-      },
-      mode: {
-        type: String,
-        default: MODE.JSON,
-      },
-      readonly: {
-        type: Boolean,
-        default: false,
-      },
-    },
+    props,
     emits: ['change'],
     setup(props, { emit }) {
       const getValue = computed(() => {
         const { value, mode } = props;
-
-        if (mode === MODE.JSON) {
-          return isString(value)
-            ? JSON.stringify(JSON.parse(value), null, 2)
-            : JSON.stringify(value, null, 2);
+        if (mode !== MODE.JSON) {
+          return value as string;
         }
-        return value;
+        return isString(value)
+          ? JSON.stringify(JSON.parse(value), null, 2)
+          : JSON.stringify(value, null, 2);
       });
 
       function handleValueChange(v) {
         emit('change', v);
       }
 
-      return {
-        handleValueChange,
-        getValue,
-      };
+      return { handleValueChange, getValue };
     },
   });
 </script>
diff --git a/src/components/CodeEditor/src/codemirror/CodeMirror.vue b/src/components/CodeEditor/src/codemirror/CodeMirror.vue
index 2ce14f8..0d50cd1 100644
--- a/src/components/CodeEditor/src/codemirror/CodeMirror.vue
+++ b/src/components/CodeEditor/src/codemirror/CodeMirror.vue
@@ -15,31 +15,25 @@
   } from 'vue';
   import { useDebounceFn } from '@vueuse/core';
   import { useAppStore } from '/@/store/modules/app';
-
+  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
   import CodeMirror from 'codemirror';
+  // css
   import './codemirror.css';
   import 'codemirror/theme/idea.css';
   import 'codemirror/theme/material-palenight.css';
-
   // modes
   import 'codemirror/mode/javascript/javascript';
   import 'codemirror/mode/css/css';
   import 'codemirror/mode/htmlmixed/htmlmixed';
+
+  const props = {
+    mode: { type: String, default: 'application/json' },
+    value: { type: String, default: '' },
+    readonly: { type: Boolean, default: false },
+  };
+
   export default defineComponent({
-    props: {
-      mode: {
-        type: String,
-        default: 'application/json',
-      },
-      value: {
-        type: String,
-        default: '',
-      },
-      readonly: {
-        type: Boolean,
-        default: false,
-      },
-    },
+    props,
     emits: ['change'],
     setup(props, { emit }) {
       const el = ref();
@@ -50,11 +44,11 @@
 
       watch(
         () => props.value,
-        async (v) => {
+        async (value) => {
           await nextTick();
           const oldValue = editor?.getValue();
-          if (v !== oldValue) {
-            editor?.setValue(v ? v : '');
+          if (value !== oldValue) {
+            editor?.setValue(value ? value : '');
           }
         },
         { flush: 'post' }
@@ -113,13 +107,13 @@
       onMounted(async () => {
         await nextTick();
         init();
-        window.addEventListener('resize', debounceRefresh);
+        useWindowSizeFn(debounceRefresh);
       });
 
       onUnmounted(() => {
-        window.removeEventListener('resize', debounceRefresh);
         editor = null;
       });
+
       return { el };
     },
   });
diff --git a/src/components/CodeEditor/src/codemirror/codemirror.css b/src/components/CodeEditor/src/codemirror/codemirror.css
index d919384..dc7c681 100644
--- a/src/components/CodeEditor/src/codemirror/codemirror.css
+++ b/src/components/CodeEditor/src/codemirror/codemirror.css
@@ -12,20 +12,21 @@
   --qualifier: #ff6032;
   --important: var(--string);
 
+  position: relative;
   height: auto;
   height: 100%;
+  overflow: hidden;
   font-family: var(--font-code);
+  background: white;
   direction: ltr;
 }
 
 /* PADDING */
 
 .CodeMirror-lines {
+  min-height: 1px; /* prevents collapsing before first draw */
   padding: 4px 0; /* Vertical padding around content */
-}
-
-.CodeMirror pre {
-  padding: 0 4px; /* Horizontal padding of content */
+  cursor: text;
 }
 
 .CodeMirror-scrollbar-filler,
@@ -36,6 +37,11 @@
 /* GUTTER */
 
 .CodeMirror-gutters {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 3;
+  min-height: 100%;
   white-space: nowrap;
   background-color: transparent;
   border-right: 1px solid #ddd;
@@ -96,7 +102,9 @@
 /* CURSOR */
 
 .CodeMirror-cursor {
+  position: absolute;
   width: 0;
+  pointer-events: none;
   border-right: none;
   border-left: 1px solid black;
 }
@@ -132,36 +140,18 @@
   animation: blink 1.06s steps(1) infinite;
 }
 @-moz-keyframes blink {
-  0% {
-  }
-
   50% {
     background-color: transparent;
-  }
-
-  100% {
   }
 }
 @-webkit-keyframes blink {
-  0% {
-  }
-
   50% {
     background-color: transparent;
-  }
-
-  100% {
   }
 }
 @keyframes blink {
-  0% {
-  }
-
   50% {
     background-color: transparent;
-  }
-
-  100% {
   }
 }
 
@@ -316,12 +306,6 @@
 /* The rest of this file contains styles related to the mechanics of
    the editor. You probably shouldn't touch them. */
 
-.CodeMirror {
-  position: relative;
-  overflow: hidden;
-  background: white;
-}
-
 .CodeMirror-scroll {
   position: relative;
   height: 100%;
@@ -378,14 +362,6 @@
   left: 0;
 }
 
-.CodeMirror-gutters {
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 3;
-  min-height: 100%;
-}
-
 .CodeMirror-gutter {
   display: inline-block;
   height: 100%;
@@ -422,14 +398,10 @@
   background-color: transparent;
 }
 
-.CodeMirror-lines {
-  min-height: 1px; /* prevents collapsing before first draw */
-  cursor: text;
-}
-
 .CodeMirror pre {
   position: relative;
   z-index: 2;
+  padding: 0 4px; /* Horizontal padding of content */
   margin: 0;
   overflow: visible;
   font-family: inherit;
@@ -495,11 +467,6 @@
   height: 0;
   overflow: hidden;
   visibility: hidden;
-}
-
-.CodeMirror-cursor {
-  position: absolute;
-  pointer-events: none;
 }
 
 .CodeMirror-measure pre {
diff --git a/src/components/CodeEditor/src/json-preview/JsonPreview.vue b/src/components/CodeEditor/src/json-preview/JsonPreview.vue
index 7ad99a2..9e3af7e 100644
--- a/src/components/CodeEditor/src/json-preview/JsonPreview.vue
+++ b/src/components/CodeEditor/src/json-preview/JsonPreview.vue
@@ -8,11 +8,7 @@
   import { defineComponent } from 'vue';
   export default defineComponent({
     name: 'JsonPreview',
-    components: {
-      VueJsonPretty,
-    },
-    props: {
-      data: Object,
-    },
+    components: { VueJsonPretty },
+    props: { data: Object },
   });
 </script>
diff --git a/src/components/Container/index.ts b/src/components/Container/index.ts
index 3fce97d..e1230a0 100644
--- a/src/components/Container/index.ts
+++ b/src/components/Container/index.ts
@@ -1,6 +1,10 @@
-import CollapseContainer from './src/collapse/CollapseContainer.vue';
-import ScrollContainer from './src/ScrollContainer.vue';
-import LazyContainer from './src/LazyContainer.vue';
+import { withInstall } from '/@/utils';
+import collapseContainer from './src/collapse/CollapseContainer.vue';
+import scrollContainer from './src/ScrollContainer.vue';
+import lazyContainer from './src/LazyContainer.vue';
 
-export { CollapseContainer, ScrollContainer, LazyContainer };
-export * from './src/types';
+export const CollapseContainer = withInstall(collapseContainer);
+export const ScrollContainer = withInstall(scrollContainer);
+export const LazyContainer = withInstall(lazyContainer);
+
+export * from './src/typing';
diff --git a/src/components/Container/src/LazyContainer.vue b/src/components/Container/src/LazyContainer.vue
index 7f7cf0c..a7ad2b6 100644
--- a/src/components/Container/src/LazyContainer.vue
+++ b/src/components/Container/src/LazyContainer.vue
@@ -18,13 +18,10 @@
 </template>
 <script lang="ts">
   import type { PropType } from 'vue';
-
   import { defineComponent, reactive, onMounted, ref, toRef, toRefs } from 'vue';
-
   import { Skeleton } from 'ant-design-vue';
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
   import { useIntersectionObserver } from '/@/hooks/event/useIntersectionObserver';
-  import { propTypes } from '/@/utils/propTypes';
 
   interface State {
     isInit: boolean;
@@ -32,36 +29,47 @@
     intersectionObserverInstance: IntersectionObserver | null;
   }
 
+  const props = {
+    /**
+     * Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time
+     */
+    timeout: { type: Number },
+    /**
+     * The viewport where the component is located.
+     * If the component is scrolling in the page container, the viewport is the container
+     */
+    viewport: {
+      type: (typeof window !== 'undefined' ? window.HTMLElement : Object) as PropType<HTMLElement>,
+      default: () => null,
+    },
+    /**
+     * Preload threshold, css unit
+     */
+    threshold: { type: String, default: '0px' },
+    /**
+     * The scroll direction of the viewport, vertical represents the vertical direction, horizontal represents the horizontal direction
+     */
+    direction: {
+      type: String,
+      default: 'vertical',
+      validator: (v) => ['vertical', 'horizontal'].includes(v),
+    },
+    /**
+     * The label name of the outer container that wraps the component
+     */
+    tag: { type: String, default: 'div' },
+    maxWaitingTime: { type: Number, default: 80 },
+    /**
+     * transition name
+     */
+    transitionName: { type: String, default: 'lazy-container' },
+  };
+
   export default defineComponent({
     name: 'LazyContainer',
     components: { Skeleton },
     inheritAttrs: false,
-    props: {
-      // Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time
-      timeout: propTypes.number,
-
-      // The viewport where the component is located. If the component is scrolling in the page container, the viewport is the container
-      viewport: {
-        type: (typeof window !== 'undefined'
-          ? window.HTMLElement
-          : Object) as PropType<HTMLElement>,
-        default: () => null,
-      },
-
-      // Preload threshold, css unit
-      threshold: propTypes.string.def('0px'),
-
-      // The scroll direction of the viewport, vertical represents the vertical direction, horizontal represents the horizontal direction
-      direction: propTypes.oneOf(['vertical', 'horizontal']).def('vertical'),
-
-      // The label name of the outer container that wraps the component
-      tag: propTypes.string.def('div'),
-
-      maxWaitingTime: propTypes.number.def(80),
-
-      // transition name
-      transitionName: propTypes.string.def('lazy-container'),
-    },
+    props,
     emits: ['init'],
     setup(props, { emit }) {
       const elRef = ref();
diff --git a/src/components/Container/src/ScrollContainer.vue b/src/components/Container/src/ScrollContainer.vue
index e85debd..dc1be2c 100644
--- a/src/components/Container/src/ScrollContainer.vue
+++ b/src/components/Container/src/ScrollContainer.vue
@@ -7,7 +7,6 @@
 <script lang="ts">
   import { defineComponent, ref, unref, nextTick } from 'vue';
   import { Scrollbar, ScrollbarType } from '/@/components/Scrollbar';
-
   import { useScrollTo } from '/@/hooks/event/useScrollTo';
 
   export default defineComponent({
@@ -16,12 +15,14 @@
     setup() {
       const scrollbarRef = ref<Nullable<ScrollbarType>>(null);
 
+      /**
+       * Scroll to the specified position
+       */
       function scrollTo(to: number, duration = 500) {
         const scrollbar = unref(scrollbarRef);
         if (!scrollbar) {
           return;
         }
-
         nextTick(() => {
           const wrap = unref(scrollbar.wrap);
           if (!wrap) {
@@ -44,12 +45,14 @@
         return scrollbar.wrap;
       }
 
+      /**
+       * Scroll to the bottom
+       */
       function scrollBottom() {
         const scrollbar = unref(scrollbarRef);
         if (!scrollbar) {
           return;
         }
-
         nextTick(() => {
           const wrap = unref(scrollbar.wrap);
           if (!wrap) {
diff --git a/src/components/Container/src/collapse/CollapseContainer.vue b/src/components/Container/src/collapse/CollapseContainer.vue
index 5c7257a..069941e 100644
--- a/src/components/Container/src/collapse/CollapseContainer.vue
+++ b/src/components/Container/src/collapse/CollapseContainer.vue
@@ -1,11 +1,6 @@
 <template>
   <div :class="prefixCls">
-    <CollapseHeader
-      v-bind="getBindValues"
-      :prefixCls="prefixCls"
-      :show="show"
-      @expand="handleExpand"
-    >
+    <CollapseHeader v-bind="$props" :prefixCls="prefixCls" :show="show" @expand="handleExpand">
       <template #title>
         <slot name="title"></slot>
       </template>
@@ -16,13 +11,12 @@
 
     <div class="p-2">
       <CollapseTransition :enable="canExpan">
-        <Skeleton v-if="loading" :active="active" />
+        <Skeleton v-if="loading" :active="loading" />
         <div :class="`${prefixCls}__body`" v-else v-show="show">
           <slot></slot>
         </div>
       </CollapseTransition>
     </div>
-
     <div :class="`${prefixCls}__footer`" v-if="$slots.footer">
       <slot name="footer"></slot>
     </div>
@@ -30,19 +24,40 @@
 </template>
 <script lang="ts">
   import type { PropType } from 'vue';
-
-  import { defineComponent, ref, computed } from 'vue';
-
+  import { defineComponent, ref } from 'vue';
   // component
   import { Skeleton } from 'ant-design-vue';
   import { CollapseTransition } from '/@/components/Transition';
   import CollapseHeader from './CollapseHeader.vue';
-
   import { triggerWindowResize } from '/@/utils/event';
   // hook
   import { useTimeoutFn } from '/@/hooks/core/useTimeout';
-  import { propTypes } from '/@/utils/propTypes';
   import { useDesign } from '/@/hooks/web/useDesign';
+
+  const props = {
+    title: { type: String, default: '' },
+    loading: { type: Boolean },
+    /**
+     *  Can it be expanded
+     */
+    canExpan: { type: Boolean, default: true },
+    /**
+     * Warm reminder on the right side of the title
+     */
+    helpMessage: {
+      type: [Array, String] as PropType<string[] | string>,
+      default: '',
+    },
+    /**
+     * Whether to trigger window.resize when expanding and contracting,
+     * Can adapt to tables and forms, when the form shrinks, the form triggers resize to adapt to the height
+     */
+    triggerWindowResize: { type: Boolean },
+    /**
+     * Delayed loading time
+     */
+    lazyTime: { type: Number, default: 0 },
+  };
 
   export default defineComponent({
     name: 'CollapseContainer',
@@ -51,23 +66,7 @@
       CollapseHeader,
       CollapseTransition,
     },
-    props: {
-      title: propTypes.string.def(''),
-      // Can it be expanded
-      canExpan: propTypes.bool.def(true),
-      // Warm reminder on the right side of the title
-      helpMessage: {
-        type: [Array, String] as PropType<string[] | string>,
-        default: '',
-      },
-      // Whether to trigger window.resize when expanding and contracting,
-      // Can adapt to tables and forms, when the form shrinks, the form triggers resize to adapt to the height
-      triggerWindowResize: propTypes.bool,
-      loading: propTypes.bool.def(false),
-      active: propTypes.bool.def(true),
-      // Delayed loading time
-      lazyTime: propTypes.number.def(0),
-    },
+    props,
     setup(props) {
       const show = ref(true);
 
@@ -84,15 +83,10 @@
         }
       }
 
-      const getBindValues = computed((): any => {
-        return props;
-      });
-
       return {
         show,
         handleExpand,
         prefixCls,
-        getBindValues,
       };
     },
   });
diff --git a/src/components/Container/src/collapse/CollapseHeader.vue b/src/components/Container/src/collapse/CollapseHeader.vue
index ee1f240..4196c0a 100644
--- a/src/components/Container/src/collapse/CollapseHeader.vue
+++ b/src/components/Container/src/collapse/CollapseHeader.vue
@@ -8,28 +8,31 @@
         <slot name="title"></slot>
       </template>
     </BasicTitle>
-
     <div :class="`${prefixCls}__action`">
       <slot name="action"></slot>
-      <BasicArrow v-if="canExpan" top :expand="show" @click="$emit('expand')" />
+      <BasicArrow v-if="canExpan" up :expand="show" @click="$emit('expand')" />
     </div>
   </div>
 </template>
 <script lang="ts">
   import { defineComponent } from 'vue';
   import { BasicArrow, BasicTitle } from '/@/components/Basic';
-  import { propTypes } from '/@/utils/propTypes';
+
+  const props = {
+    prefixCls: { type: String },
+    helpMessage: {
+      type: [Array, String] as PropType<string[] | string>,
+      default: '',
+    },
+    title: { type: String },
+    show: { type: Boolean },
+    canExpan: { type: Boolean },
+  };
 
   export default defineComponent({
     components: { BasicArrow, BasicTitle },
     inheritAttrs: false,
-    props: {
-      prefixCls: propTypes.string,
-      helpMessage: propTypes.string,
-      title: propTypes.string,
-      show: propTypes.bool,
-      canExpan: propTypes.bool,
-    },
+    props,
     emits: ['expand'],
   });
 </script>
diff --git a/src/components/Container/src/types.ts b/src/components/Container/src/typing.ts
similarity index 100%
rename from src/components/Container/src/types.ts
rename to src/components/Container/src/typing.ts
diff --git a/src/components/FlowChart/index.ts b/src/components/FlowChart/index.ts
index 3068835..edbeb55 100644
--- a/src/components/FlowChart/index.ts
+++ b/src/components/FlowChart/index.ts
@@ -1,4 +1,4 @@
-import { install } from '/@/utils/install';
+import { withInstall } from '/@/utils';
 import flowChart from './src/FlowChart.vue';
 
-export const FlowChart = install(flowChart);
+export const FlowChart = withInstall(flowChart);
diff --git a/src/components/Form/src/components/FormAction.vue b/src/components/Form/src/components/FormAction.vue
index 81a7aeb..edea5ea 100644
--- a/src/components/Form/src/components/FormAction.vue
+++ b/src/components/Form/src/components/FormAction.vue
@@ -31,7 +31,7 @@
         v-if="showAdvancedButton && !hideAdvanceBtn"
       >
         {{ isAdvanced ? t('component.form.putAway') : t('component.form.unfold') }}
-        <BasicArrow class="ml-1" :expand="!isAdvanced" top />
+        <BasicArrow class="ml-1" :expand="!isAdvanced" up />
       </Button>
       <slot name="advanceAfter"></slot>
     </FormItem>
@@ -99,16 +99,14 @@
         return actionColOpt;
       });
 
-      const getResetBtnOptions = computed(
-        (): ButtonOptions => {
-          return Object.assign(
-            {
-              text: t('common.resetText'),
-            },
-            props.resetButtonOptions
-          );
-        }
-      );
+      const getResetBtnOptions = computed((): ButtonOptions => {
+        return Object.assign(
+          {
+            text: t('common.resetText'),
+          },
+          props.resetButtonOptions
+        );
+      });
 
       const getSubmitBtnOptions = computed(() => {
         return Object.assign(
diff --git a/src/utils/index.ts b/src/utils/index.ts
index ca45a10..9aa0755 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,4 +1,6 @@
 import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router';
+import type { App, Plugin } from 'vue';
+
 import { unref } from 'vue';
 import { isObject } from '/@/utils/is';
 
@@ -76,3 +78,14 @@
       : undefined) as RouteRecordNormalized[],
   };
 }
+
+export const withInstall = <T>(component: T, alias?: string) => {
+  const comp = component as any;
+  comp.install = (app: App) => {
+    app.component(comp.name || comp.displayName, component);
+    if (alias) {
+      app.config.globalProperties[alias] = component;
+    }
+  };
+  return component as T & Plugin;
+};
diff --git a/src/utils/install.ts b/src/utils/install.ts
deleted file mode 100644
index f2687b2..0000000
--- a/src/utils/install.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { App, Plugin } from 'vue';
-
-export const install = <T>(component: T, alias?: string) => {
-  const C = component as any;
-  C.install = (app: App) => {
-    app.component(C.name, component);
-    if (alias) {
-      app.config.globalProperties[alias] = component;
-    }
-  };
-  return component as T & Plugin;
-};
diff --git a/src/views/sys/login/Login.vue b/src/views/sys/login/Login.vue
index 002eaf3..bc5071a 100644
--- a/src/views/sys/login/Login.vue
+++ b/src/views/sys/login/Login.vue
@@ -35,8 +35,7 @@
             class="
               my-auto
               mx-auto
-              xl:ml-20
-              xl:bg-transparent
+              xl:ml-20 xl:bg-transparent
               px-5
               py-8
               sm:px-8
diff --git a/types/module.d.ts b/types/module.d.ts
index 85ca8bf..8db5156 100644
--- a/types/module.d.ts
+++ b/types/module.d.ts
@@ -1,6 +1,6 @@
 declare module '*.vue' {
-  import { defineComponent } from 'vue';
-  const Component: ReturnType<typeof defineComponent>;
+  import { DefineComponent } from 'vue';
+  const Component: DefineComponent<{}, {}, any>;
   export default Component;
 }
 
diff --git a/yarn.lock b/yarn.lock
index bc5cb87..59cff62 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1191,10 +1191,10 @@
   dependencies:
     cross-fetch "^3.0.6"
 
-"@iconify/json@^1.1.353":
-  version "1.1.353"
-  resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.353.tgz#f9fb632da9b13cd79bcbea09b289610c46b87426"
-  integrity sha512-gN+DccJUhO6iB7gBPbZXodDaaxZpZTLORixrXaXNmkSW7N/jqfzMCCogoeRWOydZzSgR7VESc2tMI4llEonkjg==
+"@iconify/json@^1.1.354":
+  version "1.1.354"
+  resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.354.tgz#a2024ba18a48931e46121413ea743cddd3638fa6"
+  integrity sha512-zFW5iV4FQmu/Mhn5fUNDtESLJFuQ8Mr9B0vBM2DmKbWJmTuMoF3sfV1w3tXMCvKFAXSTUcBTdXeEYP2rWnA8jA==
 
 "@intlify/core-base@9.1.6":
   version "9.1.6"
@@ -1688,10 +1688,10 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.1.tgz#5e07e0cb2ff793aa7a1b41deae76221e6166049f"
   integrity sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw==
 
-"@types/node@^15.12.1":
-  version "15.12.1"
-  resolved "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz#9b60797dee1895383a725f828a869c86c6caa5c2"
-  integrity sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==
+"@types/node@^15.12.2":
+  version "15.12.2"
+  resolved "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
+  integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -1787,13 +1787,13 @@
     "@types/unist" "*"
     "@types/vfile-message" "*"
 
-"@typescript-eslint/eslint-plugin@^4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz#12bbd6ebd5e7fabd32e48e1e60efa1f3554a3242"
-  integrity sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==
+"@typescript-eslint/eslint-plugin@^4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz#b9c7313321cb837e2bf8bebe7acc2220659e67d3"
+  integrity sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.26.0"
-    "@typescript-eslint/scope-manager" "4.26.0"
+    "@typescript-eslint/experimental-utils" "4.26.1"
+    "@typescript-eslint/scope-manager" "4.26.1"
     debug "^4.3.1"
     functional-red-black-tree "^1.0.1"
     lodash "^4.17.21"
@@ -1801,60 +1801,60 @@
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/experimental-utils@4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.0.tgz#ba7848b3f088659cdf71bce22454795fc55be99a"
-  integrity sha512-TH2FO2rdDm7AWfAVRB5RSlbUhWxGVuxPNzGT7W65zVfl8H/WeXTk1e69IrcEVsBslrQSTDKQSaJD89hwKrhdkw==
+"@typescript-eslint/experimental-utils@4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz#a35980a2390da9232aa206b27f620eab66e94142"
+  integrity sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==
   dependencies:
     "@types/json-schema" "^7.0.7"
-    "@typescript-eslint/scope-manager" "4.26.0"
-    "@typescript-eslint/types" "4.26.0"
-    "@typescript-eslint/typescript-estree" "4.26.0"
+    "@typescript-eslint/scope-manager" "4.26.1"
+    "@typescript-eslint/types" "4.26.1"
+    "@typescript-eslint/typescript-estree" "4.26.1"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/parser@^4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.0.tgz#31b6b732c9454f757b020dab9b6754112aa5eeaf"
-  integrity sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg==
+"@typescript-eslint/parser@^4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz#cecfdd5eb7a5c13aabce1c1cfd7fbafb5a0f1e8e"
+  integrity sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.26.0"
-    "@typescript-eslint/types" "4.26.0"
-    "@typescript-eslint/typescript-estree" "4.26.0"
+    "@typescript-eslint/scope-manager" "4.26.1"
+    "@typescript-eslint/types" "4.26.1"
+    "@typescript-eslint/typescript-estree" "4.26.1"
     debug "^4.3.1"
 
-"@typescript-eslint/scope-manager@4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz#60d1a71df162404e954b9d1c6343ff3bee496194"
-  integrity sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg==
+"@typescript-eslint/scope-manager@4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz#075a74a15ff33ee3a7ed33e5fce16ee86689f662"
+  integrity sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==
   dependencies:
-    "@typescript-eslint/types" "4.26.0"
-    "@typescript-eslint/visitor-keys" "4.26.0"
+    "@typescript-eslint/types" "4.26.1"
+    "@typescript-eslint/visitor-keys" "4.26.1"
 
-"@typescript-eslint/types@4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.0.tgz#7c6732c0414f0a69595f4f846ebe12616243d546"
-  integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A==
+"@typescript-eslint/types@4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz#9e7c523f73c34b04a765e4167ca5650436ef1d38"
+  integrity sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==
 
-"@typescript-eslint/typescript-estree@4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz#aea17a40e62dc31c63d5b1bbe9a75783f2ce7109"
-  integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg==
+"@typescript-eslint/typescript-estree@4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz#b2ce2e789233d62283fae2c16baabd4f1dbc9633"
+  integrity sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==
   dependencies:
-    "@typescript-eslint/types" "4.26.0"
-    "@typescript-eslint/visitor-keys" "4.26.0"
+    "@typescript-eslint/types" "4.26.1"
+    "@typescript-eslint/visitor-keys" "4.26.1"
     debug "^4.3.1"
     globby "^11.0.3"
     is-glob "^4.0.1"
     semver "^7.3.5"
     tsutils "^3.21.0"
 
-"@typescript-eslint/visitor-keys@4.26.0":
-  version "4.26.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz#26d2583169222815be4dcd1da4fe5459bc3bcc23"
-  integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg==
+"@typescript-eslint/visitor-keys@4.26.1":
+  version "4.26.1"
+  resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz#0d55ea735cb0d8903b198017d6d4f518fdaac546"
+  integrity sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==
   dependencies:
-    "@typescript-eslint/types" "4.26.0"
+    "@typescript-eslint/types" "4.26.1"
     eslint-visitor-keys "^2.0.0"
 
 "@vitejs/plugin-legacy@^1.4.1":
@@ -2033,25 +2033,25 @@
   resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77"
   integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==
 
-"@vueuse/core@^4.11.2":
-  version "4.11.2"
-  resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-4.11.2.tgz#d4f54bd38e7c289c6f6357992c02423774cb26d9"
-  integrity sha512-4A17XvKXpMR6829EVWvrdSKEeAjTWaiC3+xh51KEtlyCwvWQwZ0xwKDrbMj+e15ANxjHrTw/0bJVaWDfPQt/Pw==
+"@vueuse/core@^5.0.1":
+  version "5.0.1"
+  resolved "https://registry.npmjs.org/@vueuse/core/-/core-5.0.1.tgz#94bbb6c71d95b79efbdb24111915775e61723f1b"
+  integrity sha512-hzcyYNvW1p9ZEwm+oBaWrHgGx6S93pJBiXLZUj2pgCNiJZjaedoePT9xzesi1SBxeKcYxwToaTISLeKdE4VKeg==
   dependencies:
-    "@vueuse/shared" "4.11.2"
+    "@vueuse/shared" "5.0.1"
     vue-demi "*"
 
-"@vueuse/shared@4.11.2":
-  version "4.11.2"
-  resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-4.11.2.tgz#1d56e08937600e3e65abf76f27cb4a1bc182adfd"
-  integrity sha512-vTbTi6ou7ljH3CkKVoaIaCAoWB5T1ewSogpL6VnO1duMPNuiv7x8K/LunMbnTg4tVyt6QwaiCuEq/kyS6AUBRg==
+"@vueuse/shared@5.0.1":
+  version "5.0.1"
+  resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-5.0.1.tgz#3b6607ffc9e19b322c39be8a2f6b584d203a7c5e"
+  integrity sha512-/+kRII9chn45PhFfRuPVbSQApJHhhqXFhPrWjnYKckMfQE9ZOuNMb1bmQnDTqzuNkoS/ENeHBMq0rnV/cfz/3Q==
   dependencies:
     vue-demi "*"
 
-"@windicss/plugin-utils@1.0.1":
-  version "1.0.1"
-  resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.0.1.tgz#f6281c91a37be5ea48eb4573cb511ccb82cce16a"
-  integrity sha512-EHsGC9LGHC/3rWNiOHzkgkexwgmxfHsqvxBoh0hLJv1MPPhEsKv8dQbt34pVZgRsS/rAjiVe4bRRM5NLTy8cWA==
+"@windicss/plugin-utils@1.0.2":
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.0.2.tgz#c34d6498058d5f4291805027d2ef6e34638a572a"
+  integrity sha512-W9fZoPNsD3NMVyqzt9eNb1DNp9p4oy7EscCfGVIg1KBxAC8S+AnXtkaR/rad09y+aqzbILKNfzDKdimDR2FA9g==
   dependencies:
     "@antfu/utils" "^0.1.6"
     debug "^4.3.2"
@@ -2059,7 +2059,7 @@
     jiti "^1.10.1"
     magic-string "^0.25.7"
     micromatch "^4.0.4"
-    windicss "^3.1.0"
+    windicss "^3.1.3"
 
 "@zxcvbn-ts/core@^0.3.0":
   version "0.3.0"
@@ -4237,11 +4237,6 @@
   resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.10.tgz#f5d39e4d9cc130b78d751664fef1b663240f5545"
   integrity sha512-XvGbf+UreVFA24Tlk6sNOqNcvF2z49XAZt4E7A4H80+yqn944QOLTTxaU0lkdYNtZKFiITNea+VxmtrfjvnLPA==
 
-esbuild@^0.12.5:
-  version "0.12.5"
-  resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.5.tgz#36076a6bc1966ba2741981d30512e95e8aaff495"
-  integrity sha512-vcuP53pA5XiwUU4FnlXM+2PnVjTfHGthM7uP1gtp+9yfheGvFFbq/KyuESThmtoHPUrfZH5JpxGVJIFDVD1Egw==
-
 esbuild@^0.12.6:
   version "0.12.6"
   resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.6.tgz#85bc755c7cf3005d4f34b4f10f98049ce0ee67ce"
@@ -4371,13 +4366,13 @@
     text-table "^0.2.0"
     v8-compile-cache "^2.0.3"
 
-esno@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.npmjs.org/esno/-/esno-0.7.0.tgz#2bec5e80eff53b60d528d6cf244445677cce7d4c"
-  integrity sha512-tOcvMYheRc7dfrxWkm4bYgmMkcNZUSt892qVY66int4L+jkEJGc64fZLx8+cZffMIcHp+4IfaTB+r+X7SoRh+g==
+esno@^0.7.1:
+  version "0.7.1"
+  resolved "https://registry.npmjs.org/esno/-/esno-0.7.1.tgz#ccd08436e0ca6e452fac1a994a7f08c61d07b7f1"
+  integrity sha512-LzI42UXMSWtt9Z7iLfytY1jqO5Mz0980NI/y8txwpBCQmXLOpkA+KFzhD3IAY+QjBOOtvFmGh2j0VR8EHY57Ww==
   dependencies:
     cross-spawn "^7.0.3"
-    esbuild "^0.12.5"
+    esbuild "^0.12.6"
     esbuild-node-loader "^0.0.0"
     esbuild-register "^2.5.0"
 
@@ -8876,10 +8871,10 @@
     source-map "^0.7.3"
     yargs "^16.2.0"
 
-rollup@^2.38.5, rollup@^2.43.1, rollup@^2.45.2, rollup@^2.51.0:
-  version "2.51.0"
-  resolved "https://registry.npmjs.org/rollup/-/rollup-2.51.0.tgz#ffd847882283998fc8611cd57af917f173b4ab5c"
-  integrity sha512-ITLt9sScNCBVspSHauw/W49lEZ0vjN8LyCzSNsNaqT67vTss2lYEfOyxltX8hjrhr1l/rQwmZ2wazzEqhZ/fUg==
+rollup@^2.38.5, rollup@^2.43.1, rollup@^2.45.2, rollup@^2.51.1:
+  version "2.51.1"
+  resolved "https://registry.npmjs.org/rollup/-/rollup-2.51.1.tgz#87bcd4095fe79b14c9bec0edc7ffa44e4827f793"
+  integrity sha512-8xfDbAtBleXotb6qKEHWuo/jkn94a9dVqGc7Rwl3sqspCVlnCfbRek7ldhCARSi7h32H0xR4QThm1t9zHN+3uw==
   optionalDependencies:
     fsevents "~2.3.1"
 
@@ -10652,15 +10647,15 @@
     esbuild-plugin-alias "^0.1.2"
     tinycolor2 "^1.4.2"
 
-vite-plugin-windicss@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.0.1.tgz#6e455228b6c1cb7ad52ed8fb9408b39888d572c0"
-  integrity sha512-+6iFKUC00G9xkR967xqbbAquaWAmgYT1rlBP7Bp6XCd9ire3b7tJTETtwSPAPAIp38OA/Xbp1MSaHhbl2LRxJg==
+vite-plugin-windicss@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.0.2.tgz#0d0fd1ff36dc81d348be755e59a8ee471941095c"
+  integrity sha512-iTmkxm8Yp+ZCFWLOs//9q3d4hYaBVDlkRGLzNBUNvRW9AQFVea57ZPhglMm9xOt1nW/O68n5Rkg4/In8rrEjHQ==
   dependencies:
-    "@windicss/plugin-utils" "1.0.1"
+    "@windicss/plugin-utils" "1.0.2"
     chalk "^4.1.1"
     debug "^4.3.2"
-    windicss "^3.1.0"
+    windicss "^3.1.3"
 
 vite@2.3.3:
   version "2.3.3"
@@ -10952,10 +10947,10 @@
   dependencies:
     string-width "^2.1.1"
 
-windicss@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.npmjs.org/windicss/-/windicss-3.1.0.tgz#bd679d51b7cabeba09077085706b48dbc1515730"
-  integrity sha512-z49xITq4X1ltHIZyL4NwFTR2LXPJ0rbOOrhDXfLX+OfG4Au7+GAzqvNlzUfAaIbA8HSpnI04alQHUWH24KfNYA==
+windicss@^3.1.3:
+  version "3.1.3"
+  resolved "https://registry.npmjs.org/windicss/-/windicss-3.1.3.tgz#a4b80af48bdd5d4be13520f700b497af455df700"
+  integrity sha512-l7fpoba2LY9AYRy4UgcuOpbPsed8UsbpEQYUVWRR1wdAwiKxK6bGIMfpiKJtjPAPdh0GOGUqr6KJar0EDZSxzg==
 
 with@^7.0.0:
   version "7.0.2"

--
Gitblit v1.8.0