Ver código fonte

chore: type Descrition,Drawer,Excel,Dropdown

Vben 3 anos atrás
pai
commit
c7c95dd2af

+ 4 - 3
src/components/Description/index.ts

@@ -1,5 +1,6 @@
-import Description from './src/Description.vue';
+import { withInstall } from '/@/utils';
+import description from './src/Description.vue';
 
-export { Description };
-export * from './src/types';
+export * from './src/typing';
 export { useDescription } from './src/useDescription';
+export const Description = withInstall(description);

+ 35 - 14
src/components/Description/src/Description.vue

@@ -1,28 +1,49 @@
 <script lang="tsx">
-  import type { DescOptions, DescInstance, DescItem } from './types';
+  import type { DescriptionProps, DescInstance, DescItem } from './typing';
   import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
   import type { CSSProperties } from 'vue';
   import type { CollapseContainerOptions } from '/@/components/Container/index';
-
   import { defineComponent, computed, ref, unref } from 'vue';
   import { get } from 'lodash-es';
   import { Descriptions } from 'ant-design-vue';
   import { CollapseContainer } from '/@/components/Container/index';
-
   import { useDesign } from '/@/hooks/web/useDesign';
-
   import { isFunction } from '/@/utils/is';
   import { getSlot } from '/@/utils/helper/tsxHelper';
-
-  import descProps from './props';
   import { useAttrs } from '/@/hooks/core/useAttrs';
 
+  const props = {
+    useCollapse: { type: Boolean, default: true },
+    title: { type: String, default: '' },
+    size: {
+      type: String,
+      validator: (v) => ['small', 'default', 'middle', undefined].includes(v),
+      default: 'small',
+    },
+    bordered: { type: Boolean, default: true },
+    column: {
+      type: [Number, Object] as PropType<number | Recordable>,
+      default: () => {
+        return { xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 };
+      },
+    },
+    collapseOptions: {
+      type: Object as PropType<CollapseContainerOptions>,
+      default: null,
+    },
+    schema: {
+      type: Array as PropType<DescItem[]>,
+      default: () => [],
+    },
+    data: { type: Object },
+  };
+
   export default defineComponent({
     name: 'Description',
-    props: descProps,
+    props,
     emits: ['register'],
     setup(props, { slots, emit }) {
-      const propsRef = ref<Partial<DescOptions> | null>(null);
+      const propsRef = ref<Partial<DescriptionProps> | null>(null);
 
       const { prefixCls } = useDesign('description');
       const attrs = useAttrs();
@@ -32,7 +53,7 @@
         return {
           ...props,
           ...(unref(propsRef) as Recordable),
-        } as DescOptions;
+        } as DescriptionProps;
       });
 
       const getProps = computed(() => {
@@ -40,7 +61,7 @@
           ...unref(getMergeProps),
           title: undefined,
         };
-        return opt as DescOptions;
+        return opt as DescriptionProps;
       });
 
       /**
@@ -66,7 +87,7 @@
       /**
        * @description:设置desc
        */
-      function setDescProps(descProps: Partial<DescOptions>): void {
+      function setDescProps(descProps: Partial<DescriptionProps>): void {
         // Keep the last setDrawerProps
         propsRef.value = { ...(unref(propsRef) as Recordable), ...descProps } as Recordable;
       }
@@ -79,7 +100,6 @@
 
         const labelStyles: CSSProperties = {
           ...labelStyle,
-
           minWidth: `${labelMinWidth}px `,
         };
         return <div style={labelStyles}>{label}</div>;
@@ -97,7 +117,9 @@
 
             const getContent = () => {
               const _data = unref(getProps)?.data;
-              if (!_data) return null;
+              if (!_data) {
+                return null;
+              }
               const getField = get(_data, field);
               return isFunction(render) ? render(getField, _data) : getField ?? '';
             };
@@ -131,7 +153,6 @@
       const renderContainer = () => {
         const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
         // Reduce the dom level
-
         if (!props.useCollapse) {
           return content;
         }

+ 0 - 25
src/components/Description/src/props.ts

@@ -1,25 +0,0 @@
-import type { PropType } from 'vue';
-import type { CollapseContainerOptions } from '/@/components/Container';
-import type { DescItem } from './types';
-import { propTypes } from '/@/utils/propTypes';
-export default {
-  useCollapse: propTypes.bool.def(true),
-  title: propTypes.string.def(''),
-  size: propTypes.oneOf(['small', 'default', 'middle', undefined]).def('small'),
-  bordered: propTypes.bool.def(true),
-  column: {
-    type: [Number, Object] as PropType<number | Recordable>,
-    default: () => {
-      return { xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 };
-    },
-  },
-  collapseOptions: {
-    type: Object as PropType<CollapseContainerOptions>,
-    default: null,
-  },
-  schema: {
-    type: Array as PropType<Array<DescItem>>,
-    default: () => [],
-  },
-  data: propTypes.object,
-};

+ 2 - 5
src/components/Description/src/types.ts → src/components/Description/src/typing.ts

@@ -4,11 +4,8 @@ import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
 
 export interface DescItem {
   labelMinWidth?: number;
-
   contentMinWidth?: number;
-
   labelStyle?: CSSProperties;
-
   field: string;
   label: string | VNode | JSX.Element;
   // Merge column
@@ -21,7 +18,7 @@ export interface DescItem {
   ) => VNode | undefined | JSX.Element | Element | string | number;
 }
 
-export interface DescOptions extends DescriptionsProps {
+export interface DescriptionProps extends DescriptionsProps {
   // Whether to include the collapse component
   useCollapse?: boolean;
   /**
@@ -42,7 +39,7 @@ export interface DescOptions extends DescriptionsProps {
 }
 
 export interface DescInstance {
-  setDescProps(descProps: Partial<DescOptions>): void;
+  setDescProps(descProps: Partial<DescriptionProps>): void;
 }
 
 export type Register = (descInstance: DescInstance) => void;

+ 12 - 11
src/components/Description/src/useDescription.ts

@@ -1,25 +1,26 @@
+import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing';
 import { ref, getCurrentInstance, unref } from 'vue';
 import { isProdMode } from '/@/utils/env';
 
-import type { DescOptions, DescInstance, UseDescReturnType } from './types';
-
-export function useDescription(props?: Partial<DescOptions>): UseDescReturnType {
+export function useDescription(props?: Partial<DescriptionProps>): UseDescReturnType {
   if (!getCurrentInstance()) {
-    throw new Error('Please put useDescription function in the setup function!');
+    throw new Error('useDescription() can only be used inside setup() or functional components!');
   }
-  const descRef = ref<Nullable<DescInstance>>(null);
-  const loadedRef = ref(false);
+  const desc = ref<Nullable<DescInstance>>(null);
+  const loaded = ref(false);
 
   function register(instance: DescInstance) {
-    if (unref(loadedRef) && isProdMode()) return;
-    descRef.value = instance;
+    if (unref(loaded) && isProdMode()) {
+      return;
+    }
+    desc.value = instance;
     props && instance.setDescProps(props);
-    loadedRef.value = true;
+    loaded.value = true;
   }
 
   const methods: DescInstance = {
-    setDescProps: (descProps: Partial<DescOptions>): void => {
-      unref(descRef)?.setDescProps(descProps);
+    setDescProps: (descProps: Partial<DescriptionProps>): void => {
+      unref(desc)?.setDescProps(descProps);
     },
   };
 

+ 4 - 3
src/components/Drawer/index.ts

@@ -1,5 +1,6 @@
-import BasicDrawer from './src/BasicDrawer.vue';
+import { withInstall } from '/@/utils';
+import basicDrawer from './src/BasicDrawer.vue';
 
-export { BasicDrawer };
-export * from './src/types';
+export const BasicDrawer = withInstall(basicDrawer);
+export * from './src/typing';
 export { useDrawer, useDrawerInner } from './src/useDrawer';

+ 2 - 6
src/components/Drawer/src/BasicDrawer.vue

@@ -31,9 +31,8 @@
   </Drawer>
 </template>
 <script lang="ts">
-  import type { DrawerInstance, DrawerProps } from './types';
+  import type { DrawerInstance, DrawerProps } from './typing';
   import type { CSSProperties } from 'vue';
-
   import {
     defineComponent,
     ref,
@@ -46,15 +45,12 @@
     getCurrentInstance,
   } from 'vue';
   import { Drawer } from 'ant-design-vue';
-
   import { useI18n } from '/@/hooks/web/useI18n';
-
   import { isFunction, isNumber } from '/@/utils/is';
   import { deepMerge } from '/@/utils';
   import DrawerFooter from './components/DrawerFooter.vue';
   import DrawerHeader from './components/DrawerHeader.vue';
   import { ScrollContainer } from '/@/components/Container';
-
   import { basicProps } from './props';
   import { useDesign } from '/@/hooks/web/useDesign';
   import { useAttrs } from '/@/hooks/core/useAttrs';
@@ -167,7 +163,7 @@
 
       function setDrawerProps(props: Partial<DrawerProps>): void {
         // Keep the last setDrawerProps
-        propsRef.value = deepMerge(unref(propsRef) || {}, props);
+        propsRef.value = deepMerge((unref(propsRef) as any) || {}, props);
 
         if (Reflect.has(props, 'visible')) {
           visibleRef.value = !!props.visible;

+ 1 - 0
src/components/Drawer/src/components/DrawerHeader.vue

@@ -40,6 +40,7 @@
       function handleClose() {
         emit('close');
       }
+
       return { prefixCls, handleClose };
     },
   });

+ 16 - 17
src/components/Drawer/src/props.ts

@@ -1,38 +1,37 @@
 import type { PropType } from 'vue';
 
 import { useI18n } from '/@/hooks/web/useI18n';
-import { propTypes } from '/@/utils/propTypes';
 const { t } = useI18n();
 
 export const footerProps = {
-  confirmLoading: propTypes.bool,
+  confirmLoading: { type: Boolean },
   /**
    * @description: Show close button
    */
-  showCancelBtn: propTypes.bool.def(true),
+  showCancelBtn: { type: Boolean, default: true },
   cancelButtonProps: Object as PropType<Recordable>,
-  cancelText: propTypes.string.def(t('common.cancelText')),
+  cancelText: { type: String, default: t('common.cancelText') },
   /**
    * @description: Show confirmation button
    */
-  showOkBtn: propTypes.bool.def(true),
+  showOkBtn: { type: Boolean, default: true },
   okButtonProps: Object as PropType<Recordable>,
-  okText: propTypes.string.def(t('common.okText')),
-  okType: propTypes.string.def('primary'),
-  showFooter: propTypes.bool,
+  okText: { type: String, default: t('common.okText') },
+  okType: { type: String, default: 'primary' },
+  showFooter: { type: Boolean },
   footerHeight: {
     type: [String, Number] as PropType<string | number>,
     default: 60,
   },
 };
 export const basicProps = {
-  isDetail: propTypes.bool,
-  title: propTypes.string.def(''),
-  loadingText: propTypes.string,
-  showDetailBack: propTypes.bool.def(true),
-  visible: propTypes.bool,
-  loading: propTypes.bool,
-  maskClosable: propTypes.bool.def(true),
+  isDetail: { type: Boolean },
+  title: { type: String, default: '' },
+  loadingText: { type: String },
+  showDetailBack: { type: Boolean, default: true },
+  visible: { type: Boolean },
+  loading: { type: Boolean },
+  maskClosable: { type: Boolean, default: true },
   getContainer: {
     type: [Object, String] as PropType<any>,
   },
@@ -44,7 +43,7 @@ export const basicProps = {
     type: [Function, Object] as PropType<any>,
     default: null,
   },
-  triggerWindowResize: propTypes.bool,
-  destroyOnClose: propTypes.bool,
+  triggerWindowResize: { type: Boolean },
+  destroyOnClose: { type: Boolean },
   ...footerProps,
 };

+ 0 - 1
src/components/Drawer/src/types.ts → src/components/Drawer/src/typing.ts

@@ -181,7 +181,6 @@ export interface DrawerProps extends DrawerFooterProps {
   placement?: 'top' | 'right' | 'bottom' | 'left';
   afterVisibleChange?: (visible?: boolean) => void;
   keyboard?: boolean;
-
   /**
    * Specify a callback that will be called when a user clicks mask, close button or Cancel button.
    */

+ 22 - 19
src/components/Drawer/src/useDrawer.ts

@@ -4,7 +4,7 @@ import type {
   ReturnMethods,
   DrawerProps,
   UseDrawerInnerReturnType,
-} from './types';
+} from './typing';
 
 import {
   ref,
@@ -32,24 +32,27 @@ const visibleData = reactive<{ [key: number]: boolean }>({});
  * @description: Applicable to separate drawer and call outside
  */
 export function useDrawer(): UseDrawerReturnType {
-  const drawerRef = ref<DrawerInstance | null>(null);
-  const loadedRef = ref<Nullable<boolean>>(false);
-  const uidRef = ref<string>('');
+  if (!getCurrentInstance()) {
+    throw new Error('useDrawer() can only be used inside setup() or functional components!');
+  }
+  const drawer = ref<DrawerInstance | null>(null);
+  const loaded = ref<Nullable<boolean>>(false);
+  const uid = ref<string>('');
 
   function register(drawerInstance: DrawerInstance, uuid: string) {
     isProdMode() &&
       tryOnUnmounted(() => {
-        drawerRef.value = null;
-        loadedRef.value = null;
-        dataTransferRef[unref(uidRef)] = null;
+        drawer.value = null;
+        loaded.value = null;
+        dataTransferRef[unref(uid)] = null;
       });
 
-    if (unref(loadedRef) && isProdMode() && drawerInstance === unref(drawerRef)) {
+    if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer)) {
       return;
     }
-    uidRef.value = uuid;
-    drawerRef.value = drawerInstance;
-    loadedRef.value = true;
+    uid.value = uuid;
+    drawer.value = drawerInstance;
+    loaded.value = true;
 
     drawerInstance.emitVisible = (visible: boolean, uid: number) => {
       visibleData[uid] = visible;
@@ -57,7 +60,7 @@ export function useDrawer(): UseDrawerReturnType {
   }
 
   const getInstance = () => {
-    const instance = unref(drawerRef);
+    const instance = unref(drawer);
     if (!instance) {
       error('useDrawer instance is undefined!');
     }
@@ -70,7 +73,7 @@ export function useDrawer(): UseDrawerReturnType {
     },
 
     getVisible: computed((): boolean => {
-      return visibleData[~~unref(uidRef)];
+      return visibleData[~~unref(uid)];
     }),
 
     openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
@@ -80,13 +83,13 @@ export function useDrawer(): UseDrawerReturnType {
       if (!data) return;
 
       if (openOnSet) {
-        dataTransferRef[unref(uidRef)] = null;
-        dataTransferRef[unref(uidRef)] = toRaw(data);
+        dataTransferRef[unref(uid)] = null;
+        dataTransferRef[unref(uid)] = toRaw(data);
         return;
       }
-      const equal = isEqual(toRaw(dataTransferRef[unref(uidRef)]), toRaw(data));
+      const equal = isEqual(toRaw(dataTransferRef[unref(uid)]), toRaw(data));
       if (!equal) {
-        dataTransferRef[unref(uidRef)] = toRaw(data);
+        dataTransferRef[unref(uid)] = toRaw(data);
       }
     },
   };
@@ -99,8 +102,8 @@ export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
   const currentInstance = getCurrentInstance();
   const uidRef = ref<string>('');
 
-  if (!currentInstance) {
-    error('useDrawerInner instance is undefined!');
+  if (!getCurrentInstance()) {
+    throw new Error('useDrawerInner() can only be used inside setup() or functional components!');
   }
 
   const getInstance = () => {

+ 4 - 3
src/components/Dropdown/index.ts

@@ -1,4 +1,5 @@
-import Dropdown from './src/Dropdown.vue';
+import { withInstall } from '/@/utils';
+import dropdown from './src/Dropdown.vue';
 
-export * from './src/types';
-export { Dropdown };
+export * from './src/typing';
+export const Dropdown = withInstall(dropdown);

+ 13 - 12
src/components/Dropdown/src/Dropdown.vue

@@ -1,12 +1,12 @@
 <template>
-  <a-dropdown :trigger="trigger" v-bind="$attrs">
+  <Dropdown :trigger="trigger" v-bind="$attrs">
     <span>
       <slot></slot>
     </span>
     <template #overlay>
-      <a-menu :selectedKeys="selectedKeys">
+      <Menu :selectedKeys="selectedKeys">
         <template v-for="item in dropMenuList" :key="`${item.event}`">
-          <a-menu-item
+          <MenuItem
             v-bind="getAttr(item.event)"
             @click="handleClickMenu(item)"
             :disabled="item.disabled"
@@ -19,17 +19,17 @@
               <Icon :icon="item.icon" v-if="item.icon" />
               <span class="ml-1">{{ item.text }}</span>
             </template>
-          </a-menu-item>
-          <a-menu-divider v-if="item.divider" :key="`d-${item.event}`" />
+          </MenuItem>
+          <MenuDivider v-if="item.divider" :key="`d-${item.event}`" />
         </template>
-      </a-menu>
+      </Menu>
     </template>
-  </a-dropdown>
+  </Dropdown>
 </template>
 
 <script lang="ts">
   import type { PropType } from 'vue';
-  import type { DropMenu } from './types';
+  import type { DropMenu } from './typing';
 
   import { defineComponent } from 'vue';
   import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
@@ -38,10 +38,10 @@
   export default defineComponent({
     name: 'BasicDropdown',
     components: {
-      [Dropdown.name]: Dropdown,
-      [Menu.name]: Menu,
-      [Menu.Item.name]: Menu.Item,
-      [Menu.Divider.name]: Menu.Divider,
+      Dropdown,
+      Menu,
+      MenuItem: Menu.Item,
+      MenuDivider: Menu.Divider,
       Icon,
       Popconfirm,
     },
@@ -75,6 +75,7 @@
         emit('menuEvent', menu);
         item.onClick?.();
       }
+
       return {
         handleClickMenu,
         getAttr: (key: string | number) => ({ key }),

+ 0 - 2
src/components/Dropdown/src/types.ts → src/components/Dropdown/src/typing.ts

@@ -7,5 +7,3 @@ export interface DropMenu {
   disabled?: boolean;
   divider?: boolean;
 }
-
-// export type Trigger = 'click' | 'hover' | 'contextMenu';

+ 6 - 6
src/components/Excel/index.ts

@@ -1,8 +1,8 @@
-import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
-
-export const ImpExcel = createAsyncComponent(() => import('./src/ImportExcel.vue'));
-export const ExpExcelModel = createAsyncComponent(() => import('./src/ExportExcelModel.vue'));
-
-export * from './src/types';
+import { withInstall } from '/@/utils';
+import impExcel from './src/ImportExcel.vue';
+import expExcelModal from './src/ExportExcelModal.vue';
 
+export const ImpExcel = withInstall(impExcel);
+export const ExpExcelModal = withInstall(expExcelModal);
+export * from './src/typing';
 export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';

+ 2 - 1
src/components/Excel/src/Export2Excel.ts

@@ -1,10 +1,11 @@
 import xlsx from 'xlsx';
 import type { WorkBook } from 'xlsx';
-import type { JsonToSheet, AoAToSheet } from './types';
+import type { JsonToSheet, AoAToSheet } from './typing';
 
 const { utils, writeFile } = xlsx;
 
 const DEF_FILE_NAME = 'excel-list.xlsx';
+
 export function jsonToSheetXlsx<T = any>({
   data,
   header,

+ 1 - 1
src/components/Excel/src/ExportExcelModel.vue → src/components/Excel/src/ExportExcelModal.vue

@@ -14,7 +14,7 @@
   </BasicModal>
 </template>
 <script lang="ts">
-  import type { ExportModalResult } from './types';
+  import type { ExportModalResult } from './typing';
   import { defineComponent } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';

+ 1 - 1
src/components/Excel/src/ImportExcel.vue

@@ -16,7 +16,7 @@
   import { defineComponent, ref, unref } from 'vue';
   import XLSX from 'xlsx';
 
-  import type { ExcelData } from './types';
+  import type { ExcelData } from './typing';
   export default defineComponent({
     name: 'ImportExcel',
     emits: ['success', 'error'],

+ 0 - 4
src/components/Excel/src/types.ts → src/components/Excel/src/typing.ts

@@ -6,10 +6,6 @@ export interface ExcelData<T = any> {
   meta: { sheetName: string };
 }
 
-// export interface ImportProps {
-//   beforeUpload: (file: File) => boolean;
-// }
-
 export interface JsonToSheet<T = any> {
   data: T[];
   header?: T;

+ 1 - 1
src/settings/localeSetting.ts

@@ -1,4 +1,4 @@
-import type { DropMenu } from '/@/components/Dropdown/src/types';
+import type { DropMenu } from '../components/Dropdown';
 import type { LocaleSetting, LocaleType } from '/#/config';
 
 export const LOCALE: { [key: string]: LocaleType } = {

+ 3 - 3
src/views/demo/excel/CustomExport.vue

@@ -5,20 +5,20 @@
         <a-button @click="openModal"> 导出 </a-button>
       </template>
     </BasicTable>
-    <ExpExcelModel @register="register" @success="defaultHeader" />
+    <ExpExcelModal @register="register" @success="defaultHeader" />
   </PageWrapper>
 </template>
 
 <script lang="ts">
   import { defineComponent } from 'vue';
   import { BasicTable } from '/@/components/Table';
-  import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
+  import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '/@/components/Excel';
   import { columns, data } from './data';
   import { useModal } from '/@/components/Modal';
   import { PageWrapper } from '/@/components/Page';
 
   export default defineComponent({
-    components: { BasicTable, ExpExcelModel, PageWrapper },
+    components: { BasicTable, ExpExcelModal, PageWrapper },
     setup() {
       function defaultHeader({ filename, bookType }: ExportModalResult) {
         // 默认Object.keys(data[0])作为header