Commit 116a1f7745fe3b89ef82d9a2376446f50623b660

Authored by vben
1 parent 405d7466

wip(table): perf table #136,146,134

Showing 64 changed files with 1859 additions and 930 deletions
CHANGELOG.zh_CN.md
@@ -14,6 +14,12 @@ @@ -14,6 +14,12 @@
14 - useForm: 支持动态改变参数。可以传入`Ref`类型与`Computed`类型进行动态更改 14 - useForm: 支持动态改变参数。可以传入`Ref`类型与`Computed`类型进行动态更改
15 - table: 新增`clickToRowSelect`属性。用于控制点击行是否选中勾选狂 15 - table: 新增`clickToRowSelect`属性。用于控制点击行是否选中勾选狂
16 - table: 监听行点击事件 16 - table: 监听行点击事件
  17 +- table: 表格列配置按钮增加 列拖拽,列固定功能。
  18 +- table:表格列配置新增`defaultHidden` 属性。用于默认隐藏。可在表格列配置勾选显示
  19 +
  20 +### ✨ Refactor
  21 +
  22 +- 重构表单,解决已知 bug
17 23
18 ### ⚡ Performance Improvements 24 ### ⚡ Performance Improvements
19 25
package.json
@@ -63,11 +63,11 @@ @@ -63,11 +63,11 @@
63 "@types/sortablejs": "^1.10.6", 63 "@types/sortablejs": "^1.10.6",
64 "@types/yargs": "^15.0.12", 64 "@types/yargs": "^15.0.12",
65 "@types/zxcvbn": "^4.4.0", 65 "@types/zxcvbn": "^4.4.0",
66 - "@typescript-eslint/eslint-plugin": "^4.11.0",  
67 - "@typescript-eslint/parser": "^4.11.0", 66 + "@typescript-eslint/eslint-plugin": "^4.11.1",
  67 + "@typescript-eslint/parser": "^4.11.1",
68 "@vue/compiler-sfc": "^3.0.4", 68 "@vue/compiler-sfc": "^3.0.4",
69 - "@vuedx/typecheck": "^0.2.4-0",  
70 - "@vuedx/typescript-plugin-vue": "^0.2.4-0", 69 + "@vuedx/typecheck": "^0.4.0",
  70 + "@vuedx/typescript-plugin-vue": "^0.4.0",
71 "autoprefixer": "^9.8.6", 71 "autoprefixer": "^9.8.6",
72 "commitizen": "^4.2.2", 72 "commitizen": "^4.2.2",
73 "conventional-changelog-cli": "^2.1.1", 73 "conventional-changelog-cli": "^2.1.1",
@@ -102,7 +102,7 @@ @@ -102,7 +102,7 @@
102 "vite-plugin-html": "^1.0.0-beta.2", 102 "vite-plugin-html": "^1.0.0-beta.2",
103 "vite-plugin-mock": "^1.0.9", 103 "vite-plugin-mock": "^1.0.9",
104 "vite-plugin-purge-icons": "^0.4.5", 104 "vite-plugin-purge-icons": "^0.4.5",
105 - "vite-plugin-pwa": "^0.2.0", 105 + "vite-plugin-pwa": "^0.2.1",
106 "vue-eslint-parser": "^7.3.0", 106 "vue-eslint-parser": "^7.3.0",
107 "yargs": "^16.2.0" 107 "yargs": "^16.2.0"
108 }, 108 },
src/App.vue
1 <template> 1 <template>
2 - <ConfigProvider  
3 - v-bind="lockEvent"  
4 - :locale="antConfigLocale"  
5 - :transform-cell-text="transformCellText"  
6 - > 2 + <ConfigProvider v-bind="lockEvent" :locale="antConfigLocale">
7 <AppProvider> 3 <AppProvider>
8 <router-view /> 4 <router-view />
9 </AppProvider> 5 </AppProvider>
@@ -14,7 +10,7 @@ @@ -14,7 +10,7 @@
14 import { defineComponent } from 'vue'; 10 import { defineComponent } from 'vue';
15 import { ConfigProvider } from 'ant-design-vue'; 11 import { ConfigProvider } from 'ant-design-vue';
16 12
17 - import { getConfigProvider, initAppConfigStore } from '/@/setup/App'; 13 + import { initAppConfigStore } from '/@/setup/App';
18 14
19 import { useLockPage } from '/@/hooks/web/useLockPage'; 15 import { useLockPage } from '/@/hooks/web/useLockPage';
20 import { useLocale } from '/@/hooks/web/useLocale'; 16 import { useLocale } from '/@/hooks/web/useLocale';
@@ -28,9 +24,6 @@ @@ -28,9 +24,6 @@
28 // Initialize vuex internal system configuration 24 // Initialize vuex internal system configuration
29 initAppConfigStore(); 25 initAppConfigStore();
30 26
31 - // Get ConfigProvider configuration  
32 - const { transformCellText } = getConfigProvider();  
33 -  
34 // Create a lock screen monitor 27 // Create a lock screen monitor
35 const lockEvent = useLockPage(); 28 const lockEvent = useLockPage();
36 29
@@ -38,7 +31,6 @@ @@ -38,7 +31,6 @@
38 const { antConfigLocale } = useLocale(); 31 const { antConfigLocale } = useLocale();
39 32
40 return { 33 return {
41 - transformCellText,  
42 antConfigLocale, 34 antConfigLocale,
43 lockEvent, 35 lockEvent,
44 }; 36 };
src/components/Button/index.ts
1 import Button from './src/BasicButton.vue'; 1 import Button from './src/BasicButton.vue';
  2 +import PopConfirmButton from './src/PopConfirmButton.vue';
2 import { withInstall } from '../util'; 3 import { withInstall } from '../util';
3 4
4 -withInstall(Button);  
5 -export { Button }; 5 +withInstall(Button, PopConfirmButton);
  6 +export { Button, PopConfirmButton };
src/components/Button/src/PopConfirmButton.vue 0 → 100644
  1 +<script lang="ts">
  2 + import { defineComponent, h, unref } from 'vue';
  3 +
  4 + import { Popconfirm } from 'ant-design-vue';
  5 + import BasicButton from './BasicButton.vue';
  6 + import { propTypes } from '/@/utils/propTypes';
  7 + import { useI18n } from '/@/hooks/web/useI18n';
  8 + import { extendSlots } from '/@/utils/helper/tsxHelper';
  9 + import { omit } from 'lodash-es';
  10 + const { t } = useI18n();
  11 +
  12 + export default defineComponent({
  13 + name: 'PopButton',
  14 + inheritAttrs: false,
  15 + components: { Popconfirm, BasicButton },
  16 + props: {
  17 + enable: propTypes.bool.def(true),
  18 + okText: propTypes.string.def(t('component.drawer.okText')),
  19 + cancelText: propTypes.string.def(t('component.drawer.cancelText')),
  20 + },
  21 + setup(props, { slots, attrs }) {
  22 + return () => {
  23 + const popValues = { ...props, ...unref(attrs) };
  24 +
  25 + const Button = h(BasicButton, omit(unref(attrs), 'icon'), extendSlots(slots));
  26 + if (!props.enable) {
  27 + return Button;
  28 + }
  29 +
  30 + return h(Popconfirm, omit(popValues, 'icon'), { default: () => Button });
  31 + };
  32 + },
  33 + });
  34 +</script>
src/components/Container/src/ScrollContainer.vue
1 <template> 1 <template>
2 - <Scrollbar  
3 - ref="scrollbarRef"  
4 - :wrapClass="`scrollbar__wrap`"  
5 - :viewClass="`scrollbar__view`"  
6 - class="scroll-container"  
7 - v-bind="$attrs"  
8 - > 2 + <Scrollbar ref="scrollbarRef" class="scroll-container" v-bind="$attrs">
9 <slot /> 3 <slot />
10 </Scrollbar> 4 </Scrollbar>
11 </template> 5 </template>
src/components/Dropdown/src/Dropdown.vue
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <template #overlay> 6 <template #overlay>
7 <a-menu :selectedKeys="selectedKeys"> 7 <a-menu :selectedKeys="selectedKeys">
8 <template v-for="item in getMenuList" :key="`${item.event}`"> 8 <template v-for="item in getMenuList" :key="`${item.event}`">
9 - <a-menu-item @click="handleClickMenu({ key: item.event })" :disabled="item.disabled"> 9 + <a-menu-item @click="handleClickMenu(item)" :disabled="item.disabled">
10 <Icon :icon="item.icon" v-if="item.icon" /> 10 <Icon :icon="item.icon" v-if="item.icon" />
11 <span class="ml-1">{{ item.text }}</span> 11 <span class="ml-1">{{ item.text }}</span>
12 </a-menu-item> 12 </a-menu-item>
@@ -59,9 +59,11 @@ @@ -59,9 +59,11 @@
59 setup(props, { emit }) { 59 setup(props, { emit }) {
60 const getMenuList = computed(() => props.dropMenuList); 60 const getMenuList = computed(() => props.dropMenuList);
61 61
62 - function handleClickMenu({ key }: { key: string }) {  
63 - const menu = unref(getMenuList).find((item) => `${item.event}` === `${key}`); 62 + function handleClickMenu(item: DropMenu) {
  63 + const { event } = item;
  64 + const menu = unref(getMenuList).find((item) => `${item.event}` === `${event}`);
64 emit('menuEvent', menu); 65 emit('menuEvent', menu);
  66 + item.onClick?.();
65 } 67 }
66 68
67 return { handleClickMenu, getMenuList }; 69 return { handleClickMenu, getMenuList };
src/components/Dropdown/src/types.ts
1 export interface DropMenu { 1 export interface DropMenu {
  2 + onClick?: Fn;
2 to?: string; 3 to?: string;
3 icon?: string; 4 icon?: string;
4 event: string | number; 5 event: string | number;
src/components/Form/src/components/ApiSelect.vue
1 <template> 1 <template>
2 - <Select v-bind="attrs" :options="options" v-model:value="state"> 2 + <Select v-bind="attrs" :options="getOptions" v-model:value="state">
3 <template #[item]="data" v-for="item in Object.keys($slots)"> 3 <template #[item]="data" v-for="item in Object.keys($slots)">
4 <slot :name="item" v-bind="data" /> 4 <slot :name="item" v-bind="data" />
5 </template> 5 </template>
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 </Select> 15 </Select>
16 </template> 16 </template>
17 <script lang="ts"> 17 <script lang="ts">
18 - import { defineComponent, PropType, ref, watchEffect } from 'vue'; 18 + import { defineComponent, PropType, ref, watchEffect, computed, unref } from 'vue';
19 import { Select } from 'ant-design-vue'; 19 import { Select } from 'ant-design-vue';
20 import { isFunction } from '/@/utils/is'; 20 import { isFunction } from '/@/utils/is';
21 import { useRuleFormItem } from '/@/hooks/component/useFormItem'; 21 import { useRuleFormItem } from '/@/hooks/component/useFormItem';
@@ -24,31 +24,31 @@ @@ -24,31 +24,31 @@
24 24
25 import { LoadingOutlined } from '@ant-design/icons-vue'; 25 import { LoadingOutlined } from '@ant-design/icons-vue';
26 import { useI18n } from '/@/hooks/web/useI18n'; 26 import { useI18n } from '/@/hooks/web/useI18n';
  27 + import { propTypes } from '/@/utils/propTypes';
27 28
28 type OptionsItem = { label: string; value: string; disabled?: boolean }; 29 type OptionsItem = { label: string; value: string; disabled?: boolean };
29 30
30 export default defineComponent({ 31 export default defineComponent({
31 - name: 'RadioButtonGroup', 32 + name: 'ApiSelect',
32 components: { 33 components: {
33 Select, 34 Select,
34 LoadingOutlined, 35 LoadingOutlined,
35 }, 36 },
36 props: { 37 props: {
37 - value: {  
38 - type: String as PropType<string>,  
39 - }, 38 + value: propTypes.string,
40 api: { 39 api: {
41 type: Function as PropType<(arg?: Recordable) => Promise<OptionsItem[]>>, 40 type: Function as PropType<(arg?: Recordable) => Promise<OptionsItem[]>>,
42 default: null, 41 default: null,
43 }, 42 },
  43 + // api params
44 params: { 44 params: {
45 type: Object as PropType<Recordable>, 45 type: Object as PropType<Recordable>,
46 default: () => {}, 46 default: () => {},
47 }, 47 },
48 - resultField: {  
49 - type: String as PropType<string>,  
50 - default: '',  
51 - }, 48 + // support xxx.xxx.xx
  49 + resultField: propTypes.string.def(''),
  50 + labelField: propTypes.string.def('label'),
  51 + valueField: propTypes.string.def('value'),
52 }, 52 },
53 setup(props) { 53 setup(props) {
54 const options = ref<OptionsItem[]>([]); 54 const options = ref<OptionsItem[]>([]);
@@ -59,6 +59,20 @@ @@ -59,6 +59,20 @@
59 // Embedded in the form, just use the hook binding to perform form verification 59 // Embedded in the form, just use the hook binding to perform form verification
60 const [state] = useRuleFormItem(props); 60 const [state] = useRuleFormItem(props);
61 61
  62 + const getOptions = computed(() => {
  63 + const { labelField, valueField } = props;
  64 +
  65 + return unref(options).reduce((prev, next: Recordable) => {
  66 + if (next) {
  67 + prev.push({
  68 + label: next[labelField],
  69 + value: next[valueField],
  70 + });
  71 + }
  72 + return prev;
  73 + }, [] as OptionsItem[]);
  74 + });
  75 +
62 watchEffect(() => { 76 watchEffect(() => {
63 fetch(); 77 fetch();
64 }); 78 });
@@ -83,7 +97,7 @@ @@ -83,7 +97,7 @@
83 loading.value = false; 97 loading.value = false;
84 } 98 }
85 } 99 }
86 - return { state, attrs, options, loading, t }; 100 + return { state, attrs, getOptions, loading, t };
87 }, 101 },
88 }); 102 });
89 </script> 103 </script>
src/components/Form/src/hooks/useFormEvents.ts
@@ -117,7 +117,7 @@ export function useFormEvents({ @@ -117,7 +117,7 @@ export function useFormEvents({
117 const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); 117 const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
118 118
119 const index = schemaList.findIndex((schema) => schema.field === prefixField); 119 const index = schemaList.findIndex((schema) => schema.field === prefixField);
120 - const hasInList = schemaList.some((item) => item.field === prefixField); 120 + const hasInList = schemaList.some((item) => item.field === prefixField || schema.field);
121 121
122 if (!hasInList) return; 122 if (!hasInList) return;
123 123
@@ -147,6 +147,7 @@ export function useFormEvents({ @@ -147,6 +147,7 @@ export function useFormEvents({
147 error( 147 error(
148 'All children of the form Schema array that need to be updated must contain the `field` field' 148 'All children of the form Schema array that need to be updated must contain the `field` field'
149 ); 149 );
  150 + return;
150 } 151 }
151 const schema: FormSchema[] = []; 152 const schema: FormSchema[] = [];
152 updateData.forEach((item) => { 153 updateData.forEach((item) => {
src/components/Preview/index.ts
1 export { createImgPreview } from './src/functional'; 1 export { createImgPreview } from './src/functional';
  2 +
  3 +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  4 +export const ImagePreview = createAsyncComponent(() => import('./src/index.vue'));
src/components/Preview/src/index.vue 0 → 100644
  1 +<template>
  2 + <PreviewGroup :class="prefixCls">
  3 + <slot v-if="!imageList || $slots.default" />
  4 + <template v-else>
  5 + <template v-for="item in getImageList" :key="item.src">
  6 + <Image v-bind="item">
  7 + <template #placeholder v-if="item.placeholder">
  8 + <Image v-bind="item" :src="item.placeholder" :preview="false" />
  9 + </template>
  10 + </Image>
  11 + </template>
  12 + </template>
  13 + </PreviewGroup>
  14 +</template>
  15 +<script lang="ts">
  16 + import type { PropType } from 'vue';
  17 + import { defineComponent, computed } from 'vue';
  18 +
  19 + import { Image } from 'ant-design-vue';
  20 + import { useDesign } from '/@/hooks/web/useDesign';
  21 + import { propTypes } from '/@/utils/propTypes';
  22 + import { ImageItem } from './types';
  23 + import { isString } from '/@/utils/is';
  24 +
  25 + export default defineComponent({
  26 + name: 'ImagePreview',
  27 + components: {
  28 + Image,
  29 + PreviewGroup: Image.PreviewGroup,
  30 + },
  31 + props: {
  32 + functional: propTypes.bool,
  33 + imageList: {
  34 + type: Array as PropType<ImageItem[]>,
  35 + },
  36 + },
  37 + setup(props) {
  38 + const { prefixCls } = useDesign('image-preview');
  39 +
  40 + const getImageList = computed(() => {
  41 + const { imageList } = props;
  42 + if (!imageList) {
  43 + return [];
  44 + }
  45 + return imageList.map((item) => {
  46 + if (isString(item)) {
  47 + return {
  48 + src: item,
  49 + placeholder: false,
  50 + };
  51 + }
  52 + return item;
  53 + });
  54 + });
  55 +
  56 + return { prefixCls, getImageList };
  57 + },
  58 + });
  59 +</script>
  60 +<style lang="less">
  61 + @import (reference) '../../../design/index.less';
  62 + @prefix-cls: ~'@{namespace}-image-preview';
  63 +
  64 + .@{prefix-cls} {
  65 + .ant-image-preview-operations {
  66 + background: rgba(0, 0, 0, 0.4);
  67 + }
  68 + }
  69 +</style>
src/components/Preview/src/types.ts
@@ -10,3 +10,21 @@ export interface Props { @@ -10,3 +10,21 @@ export interface Props {
10 imageList: string[]; 10 imageList: string[];
11 index: number; 11 index: number;
12 } 12 }
  13 +
  14 +export interface ImageProps {
  15 + alt?: string;
  16 + fallback?: string;
  17 + src: string;
  18 + width: string | number;
  19 + height?: string | number;
  20 + placeholder?: string | boolean;
  21 + preview?:
  22 + | boolean
  23 + | {
  24 + visible?: boolean;
  25 + onVisibleChange?: (visible: boolean, prevVisible: boolean) => void;
  26 + getContainer: string | HTMLElement | (() => HTMLElement);
  27 + };
  28 +}
  29 +
  30 +export type ImageItem = string | ImageProps;
src/components/Table/index.ts
  1 +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  2 +
1 export { default as BasicTable } from './src/BasicTable.vue'; 3 export { default as BasicTable } from './src/BasicTable.vue';
2 -export { default as TableAction } from './src/components/TableAction';  
3 -export { default as TableImg } from './src/components/TableImg.vue'; 4 +export { default as TableAction } from './src/components/TableAction.vue';
  5 +// export { default as TableImg } from './src/components/TableImg.vue';
4 export { renderEditableCell, renderEditableRow } from './src/components/renderEditable'; 6 export { renderEditableCell, renderEditableRow } from './src/components/renderEditable';
5 export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue'; 7 export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue';
6 8
  9 +export const TableImg = createAsyncComponent(() => import('./src/components/TableImg.vue'));
  10 +// export const TableAction = createAsyncComponent(() => import('./src/components/TableAction.vue'));
  11 +
7 export * from './src/types/table'; 12 export * from './src/types/table';
8 export * from './src/types/pagination'; 13 export * from './src/types/pagination';
9 export * from './src/types/tableAction'; 14 export * from './src/types/tableAction';
src/components/Table/src/BasicTable.vue
1 <template> 1 <template>
2 <div 2 <div
3 ref="wrapRef" 3 ref="wrapRef"
4 - class="basic-table"  
5 - :class="{  
6 - 'table-form-container': getBindValues.useSearchForm,  
7 - inset: getBindValues.inset,  
8 - }" 4 + :class="[
  5 + prefixCls,
  6 + {
  7 + [`${prefixCls}-form-container`]: getBindValues.useSearchForm,
  8 + [`${prefixCls}--inset`]: getBindValues.inset,
  9 + },
  10 + ]"
9 > 11 >
10 <BasicForm 12 <BasicForm
11 - :submitOnReset="true" 13 + submitOnReset
12 v-bind="getFormProps" 14 v-bind="getFormProps"
13 v-if="getBindValues.useSearchForm" 15 v-if="getBindValues.useSearchForm"
14 :submitButtonOptions="{ loading: getLoading }" 16 :submitButtonOptions="{ loading: getLoading }"
@@ -17,10 +19,11 @@ @@ -17,10 +19,11 @@
17 @submit="handleSearchInfoChange" 19 @submit="handleSearchInfoChange"
18 @advanced-change="redoHeight" 20 @advanced-change="redoHeight"
19 > 21 >
20 - <template #[item]="data" v-for="item in Object.keys($slots)">  
21 - <slot :name="`form-${item}`" v-bind="data" /> 22 + <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
  23 + <slot :name="item" v-bind="data" />
22 </template> 24 </template>
23 </BasicForm> 25 </BasicForm>
  26 +
24 <Table 27 <Table
25 ref="tableElRef" 28 ref="tableElRef"
26 v-bind="getBindValues" 29 v-bind="getBindValues"
@@ -38,15 +41,12 @@ @@ -38,15 +41,12 @@
38 import type { BasicTableProps, TableActionType, SizeType, SorterResult } from './types/table'; 41 import type { BasicTableProps, TableActionType, SizeType, SorterResult } from './types/table';
39 import { PaginationProps } from './types/pagination'; 42 import { PaginationProps } from './types/pagination';
40 43
41 - import { defineComponent, ref, computed, unref, watch, nextTick } from 'vue'; 44 + import { defineComponent, ref, computed, unref } from 'vue';
42 import { Table } from 'ant-design-vue'; 45 import { Table } from 'ant-design-vue';
43 - import renderTitle from './components/renderTitle';  
44 - import renderFooter from './components/renderFooter';  
45 - import renderExpandIcon from './components/renderExpandIcon';  
46 - import { BasicForm, FormProps, useForm } from '/@/components/Form/index'; 46 + import { BasicForm, useForm } from '/@/components/Form/index';
  47 +
  48 + import { isFunction } from '/@/utils/is';
47 49
48 - import { isFunction, isString } from '/@/utils/is';  
49 - import { deepMerge } from '/@/utils';  
50 import { omit } from 'lodash-es'; 50 import { omit } from 'lodash-es';
51 51
52 import { usePagination } from './hooks/usePagination'; 52 import { usePagination } from './hooks/usePagination';
@@ -55,15 +55,18 @@ @@ -55,15 +55,18 @@
55 import { useLoading } from './hooks/useLoading'; 55 import { useLoading } from './hooks/useLoading';
56 import { useRowSelection } from './hooks/useRowSelection'; 56 import { useRowSelection } from './hooks/useRowSelection';
57 import { useTableScroll } from './hooks/useTableScroll'; 57 import { useTableScroll } from './hooks/useTableScroll';
58 - import { provideTable } from './hooks/useProvinceTable';  
59 import { useCustomRow } from './hooks/useCustomRow'; 58 import { useCustomRow } from './hooks/useCustomRow';
60 import { useTableStyle } from './hooks/useTableStyle'; 59 import { useTableStyle } from './hooks/useTableStyle';
  60 + import { useTableHeader } from './hooks/useTableHeader';
  61 + import { createTableContext } from './hooks/useTableContext';
  62 + import { useTableFooter } from './hooks/useTableFooter';
  63 + import { useTableForm } from './hooks/useTableForm';
61 64
62 - import { useEventListener } from '/@/hooks/event/useEventListener';  
63 import { basicProps } from './props'; 65 import { basicProps } from './props';
64 import { useExpose } from '/@/hooks/core/useExpose'; 66 import { useExpose } from '/@/hooks/core/useExpose';
65 67
66 import './style/index.less'; 68 import './style/index.less';
  69 + import { useDesign } from '/@/hooks/web/useDesign';
67 export default defineComponent({ 70 export default defineComponent({
68 props: basicProps, 71 props: basicProps,
69 components: { Table, BasicForm }, 72 components: { Table, BasicForm },
@@ -84,7 +87,8 @@ @@ -84,7 +87,8 @@
84 const wrapRef = ref<Nullable<HTMLDivElement>>(null); 87 const wrapRef = ref<Nullable<HTMLDivElement>>(null);
85 const innerPropsRef = ref<Partial<BasicTableProps>>(); 88 const innerPropsRef = ref<Partial<BasicTableProps>>();
86 89
87 - const [registerForm, { getFieldsValue }] = useForm(); 90 + const { prefixCls } = useDesign('basic-table');
  91 + const [registerForm, formActions] = useForm();
88 92
89 const getProps = computed(() => { 93 const getProps = computed(() => {
90 return { ...props, ...unref(innerPropsRef) } as BasicTableProps; 94 return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
@@ -92,7 +96,14 @@ @@ -92,7 +96,14 @@
92 96
93 const { getLoading, setLoading } = useLoading(getProps); 97 const { getLoading, setLoading } = useLoading(getProps);
94 const { getPaginationInfo, getPagination, setPagination } = usePagination(getProps); 98 const { getPaginationInfo, getPagination, setPagination } = usePagination(getProps);
95 - const { getColumnsRef, getColumns, setColumns } = useColumns(getProps, getPaginationInfo); 99 + const {
  100 + getSortFixedColumns,
  101 + getColumns,
  102 + setColumns,
  103 + getColumnsRef,
  104 + getCacheColumns,
  105 + } = useColumns(getProps, getPaginationInfo);
  106 +
96 const { 107 const {
97 getDataSourceRef, 108 getDataSourceRef,
98 getDataSource, 109 getDataSource,
@@ -107,14 +118,13 @@ @@ -107,14 +118,13 @@
107 getPaginationInfo, 118 getPaginationInfo,
108 setLoading, 119 setLoading,
109 setPagination, 120 setPagination,
110 - getFieldsValue, 121 + getFieldsValue: formActions.getFieldsValue,
111 }, 122 },
112 emit 123 emit
113 ); 124 );
114 125
115 - const { getScrollRef, redoHeight } = useTableScroll(getProps, tableElRef);  
116 -  
117 const { 126 const {
  127 + getRowSelection,
118 getRowSelectionRef, 128 getRowSelectionRef,
119 getSelectRows, 129 getSelectRows,
120 clearSelectedRowKeys, 130 clearSelectedRowKeys,
@@ -123,6 +133,13 @@ @@ -123,6 +133,13 @@
123 setSelectedRowKeys, 133 setSelectedRowKeys,
124 } = useRowSelection(getProps, emit); 134 } = useRowSelection(getProps, emit);
125 135
  136 + const { getScrollRef, redoHeight } = useTableScroll(
  137 + getProps,
  138 + tableElRef,
  139 + getColumnsRef,
  140 + getRowSelectionRef
  141 + );
  142 +
126 const { customRow } = useCustomRow(getProps, { 143 const { customRow } = useCustomRow(getProps, {
127 setSelectedRowKeys, 144 setSelectedRowKeys,
128 getSelectRowKeys, 145 getSelectRowKeys,
@@ -131,74 +148,47 @@ @@ -131,74 +148,47 @@
131 emit, 148 emit,
132 }); 149 });
133 150
134 - const { getRowClassName } = useTableStyle(getProps); 151 + const { getRowClassName } = useTableStyle(getProps, prefixCls);
135 152
136 - const getTitleProps = computed(  
137 - (): Recordable => {  
138 - const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(getProps);  
139 - const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting;  
140 - if (hideTitle && !isString(title)) {  
141 - return {};  
142 - }  
143 - return {  
144 - title: hideTitle  
145 - ? null  
146 - : renderTitle.bind(  
147 - null,  
148 - title,  
149 - titleHelpMessage,  
150 - slots,  
151 - showTableSetting,  
152 - tableSetting  
153 - ),  
154 - };  
155 - } 153 + const { getHeaderProps } = useTableHeader(getProps, slots);
  154 +
  155 + const { getFooterProps } = useTableFooter(
  156 + getProps,
  157 + getScrollRef,
  158 + tableElRef,
  159 + getDataSourceRef
156 ); 160 );
157 161
158 - const getBindValues = computed(() => {  
159 - const { showSummary } = unref(getProps); 162 + const {
  163 + getFormProps,
  164 + replaceFormSlotKey,
  165 + getFormSlotKeys,
  166 + handleSearchInfoChange,
  167 + } = useTableForm(getProps, slots, fetch);
160 168
  169 + const getBindValues = computed(() => {
161 let propsData: Recordable = { 170 let propsData: Recordable = {
162 size: 'middle', 171 size: 'middle',
163 - ...(slots.expandedRowRender ? { expandIcon: renderExpandIcon() } : {}),  
164 ...attrs, 172 ...attrs,
165 customRow, 173 customRow,
166 ...unref(getProps), 174 ...unref(getProps),
167 - ...unref(getTitleProps), 175 + ...unref(getHeaderProps),
168 scroll: unref(getScrollRef), 176 scroll: unref(getScrollRef),
169 loading: unref(getLoading), 177 loading: unref(getLoading),
170 tableLayout: 'fixed', 178 tableLayout: 'fixed',
171 rowSelection: unref(getRowSelectionRef), 179 rowSelection: unref(getRowSelectionRef),
172 rowKey: unref(getRowKey), 180 rowKey: unref(getRowKey),
173 - columns: unref(getColumnsRef), 181 + columns: unref(getSortFixedColumns),
174 pagination: unref(getPaginationInfo), 182 pagination: unref(getPaginationInfo),
175 dataSource: unref(getDataSourceRef), 183 dataSource: unref(getDataSourceRef),
  184 + footer: unref(getFooterProps),
176 }; 185 };
177 if (slots.expandedRowRender) { 186 if (slots.expandedRowRender) {
178 propsData = omit(propsData, 'scroll'); 187 propsData = omit(propsData, 'scroll');
179 } 188 }
180 - if (showSummary) {  
181 - propsData.footer = renderFooter.bind(null, {  
182 - scroll: scroll as any,  
183 - columnsRef: getColumnsRef,  
184 - summaryFunc: unref(getProps).summaryFunc,  
185 - dataSourceRef: getDataSourceRef,  
186 - rowSelectionRef: getRowSelectionRef,  
187 - });  
188 - }  
189 return propsData; 189 return propsData;
190 }); 190 });
191 191
192 - const getFormProps = computed(() => {  
193 - const { formConfig } = unref(getProps);  
194 - const formProps: Partial<FormProps> = {  
195 - showAdvancedButton: true,  
196 - ...formConfig,  
197 - compact: true,  
198 - };  
199 - return formProps;  
200 - });  
201 -  
202 const getEmptyDataIsShowTable = computed(() => { 192 const getEmptyDataIsShowTable = computed(() => {
203 const { emptyDataIsShowTable, useSearchForm } = unref(getProps); 193 const { emptyDataIsShowTable, useSearchForm } = unref(getProps);
204 if (emptyDataIsShowTable || !useSearchForm) { 194 if (emptyDataIsShowTable || !useSearchForm) {
@@ -207,22 +197,6 @@ @@ -207,22 +197,6 @@
207 return !!unref(getDataSourceRef).length; 197 return !!unref(getDataSourceRef).length;
208 }); 198 });
209 199
210 - watch(  
211 - () => unref(getDataSourceRef),  
212 - () => {  
213 - handleSummary();  
214 - },  
215 - { immediate: true }  
216 - );  
217 -  
218 - function handleSearchInfoChange(info: any) {  
219 - const { handleSearchInfoFn } = unref(getProps);  
220 - if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) {  
221 - info = handleSearchInfoFn(info) || info;  
222 - }  
223 - fetch({ searchInfo: info, page: 1 });  
224 - }  
225 -  
226 function handleTableChange( 200 function handleTableChange(
227 pagination: PaginationProps, 201 pagination: PaginationProps,
228 // @ts-ignore 202 // @ts-ignore
@@ -243,32 +217,8 @@ @@ -243,32 +217,8 @@
243 fetch(); 217 fetch();
244 } 218 }
245 219
246 - function handleSummary() {  
247 - if (unref(getProps).showSummary) {  
248 - nextTick(() => {  
249 - const tableEl = unref(tableElRef);  
250 - if (!tableEl) return;  
251 - const bodyDomList = tableEl.$el.querySelectorAll('.ant-table-body');  
252 - const bodyDom = bodyDomList[0];  
253 - useEventListener({  
254 - el: bodyDom,  
255 - name: 'scroll',  
256 - listener: () => {  
257 - const footerBodyDom = tableEl.$el.querySelector(  
258 - '.ant-table-footer .ant-table-body'  
259 - ) as HTMLDivElement;  
260 - if (!footerBodyDom || !bodyDom) return;  
261 - footerBodyDom.scrollLeft = bodyDom.scrollLeft;  
262 - },  
263 - wait: 0,  
264 - options: true,  
265 - });  
266 - });  
267 - }  
268 - }  
269 -  
270 function setProps(props: Partial<BasicTableProps>) { 220 function setProps(props: Partial<BasicTableProps>) {
271 - innerPropsRef.value = deepMerge(unref(innerPropsRef) || {}, props); 221 + innerPropsRef.value = { ...unref(innerPropsRef), ...props };
272 } 222 }
273 223
274 const tableAction: TableActionType = { 224 const tableAction: TableActionType = {
@@ -285,21 +235,19 @@ @@ -285,21 +235,19 @@
285 setLoading, 235 setLoading,
286 getDataSource, 236 getDataSource,
287 setProps, 237 setProps,
  238 + getRowSelection,
288 getPaginationRef: getPagination, 239 getPaginationRef: getPagination,
289 getColumns, 240 getColumns,
  241 + getCacheColumns,
290 getSize: () => { 242 getSize: () => {
291 return unref(getBindValues).size as SizeType; 243 return unref(getBindValues).size as SizeType;
292 }, 244 },
293 }; 245 };
294 -  
295 - provideTable({  
296 - ...tableAction,  
297 - wrapRef,  
298 - }); 246 + createTableContext({ ...tableAction, wrapRef, getBindValues });
299 247
300 useExpose<TableActionType>(tableAction); 248 useExpose<TableActionType>(tableAction);
301 249
302 - emit('register', tableAction); 250 + emit('register', tableAction, formActions);
303 251
304 return { 252 return {
305 tableElRef, 253 tableElRef,
@@ -307,13 +255,16 @@ @@ -307,13 +255,16 @@
307 getLoading, 255 getLoading,
308 registerForm, 256 registerForm,
309 handleSearchInfoChange, 257 handleSearchInfoChange,
310 - getFormProps,  
311 getEmptyDataIsShowTable, 258 getEmptyDataIsShowTable,
312 handleTableChange, 259 handleTableChange,
313 getRowClassName, 260 getRowClassName,
314 wrapRef, 261 wrapRef,
315 tableAction, 262 tableAction,
316 redoHeight, 263 redoHeight,
  264 + getFormProps,
  265 + replaceFormSlotKey,
  266 + getFormSlotKeys,
  267 + prefixCls,
317 }; 268 };
318 }, 269 },
319 }); 270 });
src/components/Table/src/components/TableAction.tsx deleted 100644 → 0
1 -import { defineComponent, PropType } from 'vue';  
2 -import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';  
3 -import Icon from '/@/components/Icon/index';  
4 -import { DownOutlined } from '@ant-design/icons-vue';  
5 -import { ActionItem } from '/@/components/Table';  
6 -import { Button } from '/@/components/Button';  
7 -import { snowUuid } from '/@/utils/uuid';  
8 -const prefixCls = 'basic-table-action';  
9 -export default defineComponent({  
10 - name: 'TableAction',  
11 - props: {  
12 - actions: {  
13 - type: Array as PropType<ActionItem[]>,  
14 - default: null,  
15 - },  
16 - dropDownActions: {  
17 - type: Array as PropType<ActionItem[]>,  
18 - default: null,  
19 - },  
20 -  
21 - moreText: {  
22 - type: String as PropType<string>,  
23 - default: '更多',  
24 - },  
25 - },  
26 - setup(props) {  
27 - function renderButton(action: ActionItem) {  
28 - const { disabled = false, label, icon, color = '', type = 'link', ...actionProps } = action;  
29 - const button = (  
30 - <Button  
31 - type={type}  
32 - size="small"  
33 - disabled={disabled}  
34 - color={color}  
35 - {...actionProps}  
36 - key={`${snowUuid()}`}  
37 - >  
38 - {() => (  
39 - <>  
40 - {icon && <Icon icon={icon} class="mr-1" />}  
41 - {label}  
42 - </>  
43 - )}  
44 - </Button>  
45 - );  
46 - return button;  
47 - }  
48 -  
49 - function renderPopConfirm(action: ActionItem) {  
50 - const { popConfirm = null } = action;  
51 - if (!popConfirm) {  
52 - return renderButton(action);  
53 - }  
54 - const {  
55 - title,  
56 - okText = '确定',  
57 - cancelText = '取消',  
58 - confirm = () => {},  
59 - cancel = () => {},  
60 - icon = '',  
61 - } = popConfirm;  
62 - return (  
63 - <Popconfirm  
64 - key={`${snowUuid()}`}  
65 - title={title}  
66 - onConfirm={confirm}  
67 - onCancel={cancel}  
68 - okText={okText}  
69 - cancelText={cancelText}  
70 - icon={icon}  
71 - >  
72 - {() => renderButton(action)}  
73 - </Popconfirm>  
74 - );  
75 - }  
76 -  
77 - const dropdownDefaultSLot = () => (  
78 - <Button type="link" size="small">  
79 - {{  
80 - default: () => (  
81 - <>  
82 - {props.moreText}  
83 - <DownOutlined />  
84 - </>  
85 - ),  
86 - }}  
87 - </Button>  
88 - );  
89 -  
90 - // 增加按钮的TYPE和COLOR  
91 - return () => {  
92 - const { dropDownActions = [], actions } = props;  
93 - return (  
94 - <div class={prefixCls}>  
95 - {actions &&  
96 - actions.map((action) => {  
97 - return renderPopConfirm(action);  
98 - })}  
99 - {dropDownActions && dropDownActions.length && (  
100 - <Dropdown overlayClassName="basic-tale-action-dropdown">  
101 - {{  
102 - default: dropdownDefaultSLot,  
103 - overlay: () => {  
104 - return (  
105 - <Menu>  
106 - {{  
107 - default: () => {  
108 - return dropDownActions.map((action) => {  
109 - const { disabled = false } = action;  
110 - action.ghost = true;  
111 - return (  
112 - <Menu.Item key={`${snowUuid()}`} disabled={disabled}>  
113 - {() => {  
114 - return renderPopConfirm(action);  
115 - }}  
116 - </Menu.Item>  
117 - );  
118 - });  
119 - },  
120 - }}  
121 - </Menu>  
122 - );  
123 - },  
124 - }}  
125 - </Dropdown>  
126 - )}  
127 - </div>  
128 - );  
129 - };  
130 - },  
131 -});  
src/components/Table/src/components/TableAction.vue 0 → 100644
  1 +<template>
  2 + <div :class="[prefixCls, getAlign]">
  3 + <template v-for="(action, index) in getActions" :key="`${index}`">
  4 + <PopConfirmButton v-bind="action">
  5 + <Icon :icon="action.icon" class="mr-1" v-if="action.icon" />
  6 + {{ action.label }}
  7 + </PopConfirmButton>
  8 + <Divider type="vertical" v-if="divider && index < getActions.length" />
  9 + </template>
  10 +
  11 + <Dropdown :trigger="['hover']" :dropMenuList="getDropList">
  12 + <slot name="more" />
  13 + <a-button type="link" size="small" v-if="!$slots.more">
  14 + <MoreOutlined class="icon-more" />
  15 + </a-button>
  16 + </Dropdown>
  17 + </div>
  18 +</template>
  19 +<script lang="ts">
  20 + import { defineComponent, PropType, computed } from 'vue';
  21 + import Icon from '/@/components/Icon/index';
  22 + import { ActionItem } from '/@/components/Table';
  23 + import { PopConfirmButton } from '/@/components/Button';
  24 + import { Divider } from 'ant-design-vue';
  25 + import { Dropdown } from '/@/components/Dropdown';
  26 + import { useDesign } from '/@/hooks/web/useDesign';
  27 + import { MoreOutlined } from '@ant-design/icons-vue';
  28 + import { propTypes } from '/@/utils/propTypes';
  29 + import { useTableContext } from '../hooks/useTableContext';
  30 + import { ACTION_COLUMN_FLAG } from '../const';
  31 + export default defineComponent({
  32 + name: 'TableAction',
  33 + components: { Icon, PopConfirmButton, Divider, Dropdown, MoreOutlined },
  34 + props: {
  35 + actions: {
  36 + type: Array as PropType<ActionItem[]>,
  37 + default: null,
  38 + },
  39 + dropDownActions: {
  40 + type: Array as PropType<ActionItem[]>,
  41 + default: null,
  42 + },
  43 + divider: propTypes.bool.def(true),
  44 + },
  45 + setup(props) {
  46 + const { prefixCls } = useDesign('basic-table-action');
  47 + const table = useTableContext();
  48 + const getActions = computed(() => {
  49 + return props.actions.map((action) => {
  50 + const { popConfirm } = action;
  51 + return {
  52 + ...action,
  53 + ...(popConfirm || {}),
  54 + onConfirm: popConfirm?.confirm,
  55 + onCancel: popConfirm?.cancel,
  56 + enable: !!popConfirm,
  57 + type: 'link',
  58 + size: 'small',
  59 + };
  60 + });
  61 + });
  62 +
  63 + const getDropList = computed(() => {
  64 + return props.dropDownActions.map((action, index) => {
  65 + const { label } = action;
  66 + return {
  67 + ...action,
  68 + text: label,
  69 + divider: index < props.dropDownActions.length - 1 ? props.divider : false,
  70 + };
  71 + });
  72 + });
  73 +
  74 + const getAlign = computed(() => {
  75 + const columns = table.getColumns();
  76 + const actionColumn = columns.find((item) => item.flag === ACTION_COLUMN_FLAG);
  77 + return actionColumn?.align ?? 'left';
  78 + });
  79 +
  80 + return { prefixCls, getActions, getDropList, getAlign };
  81 + },
  82 + });
  83 +</script>
  84 +<style lang="less">
  85 + @prefix-cls: ~'@{namespace}-basic-table-action';
  86 +
  87 + .@{prefix-cls} {
  88 + display: flex;
  89 + align-items: center;
  90 +
  91 + &.left {
  92 + justify-content: flex-start;
  93 + }
  94 +
  95 + &.center {
  96 + justify-content: center;
  97 + }
  98 +
  99 + &.right {
  100 + justify-content: flex-end;
  101 + }
  102 +
  103 + button {
  104 + display: flex;
  105 + align-items: center;
  106 +
  107 + span {
  108 + margin-left: 0 !important;
  109 + }
  110 + }
  111 +
  112 + .ant-divider,
  113 + .ant-divider-vertical {
  114 + margin: 0 2px;
  115 + }
  116 +
  117 + .icon-more {
  118 + transform: rotate(90deg);
  119 +
  120 + svg {
  121 + font-size: 1.1em;
  122 + font-weight: 700;
  123 + }
  124 + }
  125 + }
  126 +</style>
src/components/Table/src/components/TableFooter.vue 0 → 100644
  1 +<template>
  2 + <Table
  3 + v-if="summaryFunc"
  4 + :showHeader="false"
  5 + :bordered="false"
  6 + :pagination="false"
  7 + :dataSource="getDataSource"
  8 + :rowKey="(r) => r[rowKey]"
  9 + :columns="getColumns"
  10 + tableLayout="fixed"
  11 + :scroll="scroll"
  12 + />
  13 +</template>
  14 +<script lang="ts">
  15 + import type { PropType } from 'vue';
  16 +
  17 + import { defineComponent, unref, computed, toRaw } from 'vue';
  18 + import { Table } from 'ant-design-vue';
  19 + import { cloneDeep } from 'lodash-es';
  20 + import { isFunction } from '/@/utils/is';
  21 + import type { BasicColumn } from '../types/table';
  22 + import { INDEX_COLUMN_FLAG } from '../const';
  23 + import { propTypes } from '/@/utils/propTypes';
  24 + import { useTableContext } from '../hooks/useTableContext';
  25 +
  26 + const SUMMARY_ROW_KEY = '_row';
  27 + const SUMMARY_INDEX_KEY = '_index';
  28 + export default defineComponent({
  29 + name: 'BasicTableFooter',
  30 + components: { Table },
  31 + props: {
  32 + summaryFunc: {
  33 + type: Function as PropType<Fn>,
  34 + },
  35 + scroll: {
  36 + type: Object as PropType<Recordable>,
  37 + },
  38 + rowKey: propTypes.string.def('key'),
  39 + },
  40 + setup(props) {
  41 + const table = useTableContext();
  42 +
  43 + const getDataSource = computed((): Recordable[] => {
  44 + const { summaryFunc } = props;
  45 + if (!isFunction(summaryFunc)) {
  46 + return [];
  47 + }
  48 + let dataSource = toRaw(unref(table.getDataSource()));
  49 + dataSource = summaryFunc(dataSource);
  50 + dataSource.forEach((item, i) => {
  51 + item[props.rowKey] = `${i}`;
  52 + });
  53 + return dataSource;
  54 + });
  55 +
  56 + const getColumns = computed(() => {
  57 + const dataSource = unref(getDataSource);
  58 + const columns: BasicColumn[] = cloneDeep(table.getColumns());
  59 + const index = columns.findIndex((item) => item.flag === INDEX_COLUMN_FLAG);
  60 + const hasRowSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_ROW_KEY));
  61 + const hasIndexSummary = dataSource.some((item) => Reflect.has(item, SUMMARY_INDEX_KEY));
  62 +
  63 + if (index !== -1) {
  64 + if (hasIndexSummary) {
  65 + columns[index].customRender = ({ record }) => record[SUMMARY_INDEX_KEY];
  66 + columns[index].ellipsis = false;
  67 + } else {
  68 + Reflect.deleteProperty(columns[index], 'customRender');
  69 + }
  70 + }
  71 + if (table.getRowSelection() && hasRowSummary) {
  72 + columns.unshift({
  73 + width: 60,
  74 + title: 'selection',
  75 + key: 'selectionKey',
  76 + align: 'center',
  77 + customRender: ({ record }) => record[SUMMARY_ROW_KEY],
  78 + });
  79 + }
  80 + return columns;
  81 + });
  82 + return { getColumns, getDataSource };
  83 + },
  84 + });
  85 +</script>
src/components/Table/src/components/TableHeader.vue 0 → 100644
  1 +<template>
  2 + <slot name="tableTitle" v-if="$slots.tableTitle" />
  3 + <TableTitle :helpMessage="titleHelpMessage" :title="title" v-if="!$slots.tableTitle && title" />
  4 +
  5 + <div :class="`${prefixCls}__toolbar`">
  6 + <slot name="toolbar" />
  7 + <Divider type="vertical" v-if="$slots.toolbar" />
  8 + <TableSetting :setting="tableSetting" v-if="showTableSetting" />
  9 + </div>
  10 +</template>
  11 +<script lang="ts">
  12 + import type { TableSetting } from '../types/table';
  13 + import type { PropType } from 'vue';
  14 + import { Divider } from 'ant-design-vue';
  15 + import { defineComponent } from 'vue';
  16 +
  17 + import { useDesign } from '/@/hooks/web/useDesign';
  18 + import TableSettingComp from './settings/index.vue';
  19 + import TableTitle from './TableTitle.vue';
  20 +
  21 + export default defineComponent({
  22 + name: 'BasicTableHeader',
  23 + components: {
  24 + Divider,
  25 + TableTitle,
  26 + TableSetting: TableSettingComp,
  27 + },
  28 + props: {
  29 + title: {
  30 + type: [Function, String] as PropType<string | ((data: Recordable) => string)>,
  31 + },
  32 + tableSetting: {
  33 + type: Object as PropType<TableSetting>,
  34 + },
  35 + showTableSetting: {
  36 + type: Boolean,
  37 + },
  38 + titleHelpMessage: {
  39 + type: [String, Array] as PropType<string | string[]>,
  40 + default: '',
  41 + },
  42 + },
  43 + setup() {
  44 + const { prefixCls } = useDesign('basic-table-header');
  45 + return { prefixCls };
  46 + },
  47 + });
  48 +</script>
  49 +<style lang="less">
  50 + @prefix-cls: ~'@{namespace}-basic-table-header';
  51 +
  52 + .@{prefix-cls} {
  53 + &__toolbar {
  54 + flex: 1;
  55 + display: flex;
  56 + align-items: center;
  57 + justify-content: flex-end;
  58 +
  59 + > * {
  60 + margin-right: 8px;
  61 + }
  62 + }
  63 + }
  64 +</style>
src/components/Table/src/components/TableImg.vue
1 <template> 1 <template>
2 - <div class="basic-table-img__preview" v-if="imgList && imgList.length">  
3 - <template v-for="(img, index) in imgList" :key="img">  
4 - <img :width="size" @click="handlePreview(index)" :src="img" />  
5 - </template> 2 + <div :class="prefixCls" v-if="imgList && imgList.length">
  3 + <PreviewGroup>
  4 + <template v-for="img in imgList" :key="img">
  5 + <Image :width="size" :src="img" />
  6 + </template>
  7 + </PreviewGroup>
6 </div> 8 </div>
7 </template> 9 </template>
8 <script lang="ts"> 10 <script lang="ts">
9 import { defineComponent, PropType } from 'vue'; 11 import { defineComponent, PropType } from 'vue';
10 - import { createImgPreview } from '/@/components/Preview/index'; 12 + import { useDesign } from '/@/hooks/web/useDesign';
  13 +
  14 + import { Image } from 'ant-design-vue';
11 15
12 export default defineComponent({ 16 export default defineComponent({
13 - name: 'TableAction', 17 + name: 'TableImage',
  18 + components: { Image, PreviewGroup: Image.PreviewGroup },
14 props: { 19 props: {
15 imgList: { 20 imgList: {
16 type: Array as PropType<string[]>, 21 type: Array as PropType<string[]>,
@@ -21,16 +26,25 @@ @@ -21,16 +26,25 @@
21 default: 40, 26 default: 40,
22 }, 27 },
23 }, 28 },
24 - setup(props) {  
25 - function handlePreview(index: number) {  
26 - const { imgList } = props;  
27 -  
28 - createImgPreview({  
29 - imageList: imgList as string[],  
30 - index: index,  
31 - });  
32 - }  
33 - return { handlePreview }; 29 + setup() {
  30 + const { prefixCls } = useDesign('basic-table-img');
  31 + return { prefixCls };
34 }, 32 },
35 }); 33 });
36 </script> 34 </script>
  35 +<style lang="less">
  36 + @prefix-cls: ~'@{namespace}-basic-table-img';
  37 +
  38 + .@{prefix-cls} {
  39 + display: flex;
  40 +
  41 + .ant-image {
  42 + margin-right: 4px;
  43 + cursor: zoom-in;
  44 +
  45 + img {
  46 + border-radius: 2px;
  47 + }
  48 + }
  49 + }
  50 +</style>
src/components/Table/src/components/TableSetting.vue deleted 100644 → 0
1 -<template>  
2 - <div class="table-settings">  
3 - <Divider type="vertical" />  
4 -  
5 - <Tooltip placement="top" v-if="getSetting.redo">  
6 - <template #title>  
7 - <span>{{ t('component.table.settingRedo') }}</span>  
8 - </template>  
9 - <RedoOutlined @click="redo" />  
10 - </Tooltip>  
11 -  
12 - <Tooltip placement="top" v-if="getSetting.size">  
13 - <template #title>  
14 - <span>{{ t('component.table.settingDens') }}</span>  
15 - </template>  
16 - <Dropdown placement="bottomCenter" :trigger="['click']">  
17 - <ColumnHeightOutlined />  
18 - <template #overlay>  
19 - <Menu @click="handleTitleClick" selectable v-model:selectedKeys="selectedKeysRef">  
20 - <MenuItem key="default">  
21 - <span>{{ t('component.table.settingDensDefault') }}</span>  
22 - </MenuItem>  
23 - <MenuItem key="middle">  
24 - <span>{{ t('component.table.settingDensMiddle') }}</span>  
25 - </MenuItem>  
26 - <MenuItem key="small">  
27 - <span>{{ t('component.table.settingDensSmall') }}</span>  
28 - </MenuItem>  
29 - </Menu>  
30 - </template>  
31 - </Dropdown>  
32 - </Tooltip>  
33 -  
34 - <Tooltip placement="top" v-if="getSetting.setting">  
35 - <template #title>  
36 - <span>{{ t('component.table.settingColumn') }}</span>  
37 - </template>  
38 - <Popover  
39 - placement="bottomLeft"  
40 - trigger="click"  
41 - overlayClassName="table-settings__cloumn-list"  
42 - >  
43 - <template #content>  
44 - <CheckboxGroup v-model:value="checkedList" @change="onChange">  
45 - <template v-for="item in plainOptions" :key="item.value">  
46 - <div class="table-settings__check-item">  
47 - <Checkbox :value="item.value">  
48 - {{ item.label }}  
49 - </Checkbox>  
50 - </div>  
51 - </template>  
52 - </CheckboxGroup>  
53 - </template>  
54 - <template #title>  
55 - <div class="table-settings__popover-title">  
56 - <Checkbox  
57 - :indeterminate="indeterminate"  
58 - v-model:checked="checkAll"  
59 - @change="onCheckAllChange"  
60 - >  
61 - {{ t('component.table.settingColumnShow') }}  
62 - </Checkbox>  
63 - <a-button size="small" type="link" @click="reset">  
64 - {{ t('component.table.settingReset') }}</a-button  
65 - >  
66 - </div>  
67 - </template>  
68 - <SettingOutlined />  
69 - </Popover>  
70 - </Tooltip>  
71 -  
72 - <Tooltip placement="top" v-if="getSetting.fullScreen">  
73 - <template #title>  
74 - <span>{{ t('component.table.settingFullScreen') }}</span>  
75 - </template>  
76 - <FullscreenOutlined @click="handleFullScreen" v-if="!isFullscreenRef" />  
77 - <FullscreenExitOutlined @click="handleFullScreen" v-else />  
78 - </Tooltip>  
79 - </div>  
80 -</template>  
81 -<script lang="ts">  
82 - import { defineComponent, ref, reactive, toRefs, PropType, computed, watchEffect } from 'vue';  
83 - import { injectTable } from '../hooks/useProvinceTable';  
84 - import { Tooltip, Divider, Dropdown, Menu, Popover, Checkbox } from 'ant-design-vue';  
85 - import {  
86 - RedoOutlined,  
87 - ColumnHeightOutlined,  
88 - FullscreenOutlined,  
89 - FullscreenExitOutlined,  
90 - SettingOutlined,  
91 - } from '@ant-design/icons-vue';  
92 - import { useFullscreen } from '/@/hooks/web/useFullScreen';  
93 - import type { SizeType, TableSetting } from '../types/table';  
94 - import { useI18n } from '/@/hooks/web/useI18n';  
95 -  
96 - interface Options {  
97 - label: string;  
98 - value: string;  
99 - }  
100 - interface State {  
101 - indeterminate: boolean;  
102 - checkAll: boolean;  
103 - // defaultColumns: BasicColumn[];  
104 - // columns: BasicColumn[];  
105 - checkedList: string[];  
106 - defaultCheckList: string[];  
107 - }  
108 - export default defineComponent({  
109 - name: 'TableSetting',  
110 - components: {  
111 - RedoOutlined,  
112 - ColumnHeightOutlined,  
113 - FullscreenExitOutlined,  
114 - FullscreenOutlined,  
115 - SettingOutlined,  
116 - Popover,  
117 - Tooltip,  
118 - Divider,  
119 - Dropdown,  
120 - Checkbox,  
121 - CheckboxGroup: Checkbox.Group,  
122 - Menu,  
123 - MenuItem: Menu.Item,  
124 - },  
125 - props: {  
126 - setting: {  
127 - type: Object as PropType<TableSetting>,  
128 - default: {},  
129 - },  
130 - },  
131 - setup(props) {  
132 - const table = injectTable();  
133 - const { toggleFullscreen, isFullscreenRef } = useFullscreen(table.wrapRef);  
134 - const selectedKeysRef = ref<SizeType[]>([table.getSize()]);  
135 -  
136 - const plainOptions = ref<Options[]>([]);  
137 - const state = reactive<State>({  
138 - indeterminate: false,  
139 - checkAll: true,  
140 - checkedList: [],  
141 - defaultCheckList: [],  
142 - });  
143 -  
144 - const { t } = useI18n();  
145 -  
146 - watchEffect(() => {  
147 - const columns = table.getColumns();  
148 - if (columns.length) {  
149 - init();  
150 - }  
151 - });  
152 -  
153 - function init() {  
154 - let ret: Options[] = [];  
155 - table.getColumns({ ignoreIndex: true, ignoreAction: true }).forEach((item) => {  
156 - ret.push({  
157 - label: item.title as string,  
158 - value: (item.dataIndex || item.title) as string,  
159 - });  
160 - });  
161 - if (!plainOptions.value.length) {  
162 - plainOptions.value = ret;  
163 - }  
164 - const checkList = table  
165 - .getColumns()  
166 - .map((item) => item.dataIndex || item.title) as string[];  
167 - state.checkedList = checkList;  
168 - state.defaultCheckList = checkList;  
169 - }  
170 -  
171 - function handleTitleClick({ key }: { key: SizeType }) {  
172 - selectedKeysRef.value = [key];  
173 - table.setProps({  
174 - size: key,  
175 - });  
176 - }  
177 -  
178 - function handleFullScreen() {  
179 - toggleFullscreen();  
180 - }  
181 -  
182 - function onCheckAllChange(e: ChangeEvent) {  
183 - state.indeterminate = false;  
184 - const checkList = plainOptions.value.map((item) => item.value);  
185 - if (e.target.checked) {  
186 - state.checkedList = checkList;  
187 - table.setColumns(checkList);  
188 - } else {  
189 - state.checkedList = [];  
190 - table.setColumns([]);  
191 - }  
192 - }  
193 -  
194 - function onChange(checkedList: string[]) {  
195 - const len = plainOptions.value.length;  
196 - state.indeterminate = !!checkedList.length && checkedList.length < len;  
197 - state.checkAll = checkedList.length === len;  
198 - table.setColumns(checkedList);  
199 - }  
200 -  
201 - function reset() {  
202 - if (state.checkAll) return;  
203 - state.checkedList = [...state.defaultCheckList];  
204 - state.checkAll = true;  
205 - state.indeterminate = false;  
206 - table.setColumns(state.defaultCheckList);  
207 - }  
208 -  
209 - const getSetting = computed(  
210 - (): TableSetting => {  
211 - return {  
212 - redo: true,  
213 - size: true,  
214 - setting: true,  
215 - fullScreen: true,  
216 - ...props.setting,  
217 - };  
218 - }  
219 - );  
220 -  
221 - return {  
222 - redo: () => table.reload(),  
223 - handleTitleClick,  
224 - selectedKeysRef,  
225 - handleFullScreen,  
226 - isFullscreenRef,  
227 - onCheckAllChange,  
228 - onChange,  
229 - plainOptions,  
230 - reset,  
231 - getSetting,  
232 - ...toRefs(state),  
233 - t,  
234 - };  
235 - },  
236 - });  
237 -</script>  
238 -<style lang="less">  
239 - @import (reference) '../../../../design/index.less';  
240 -  
241 - .table-settings {  
242 - & > * {  
243 - margin-right: 12px;  
244 - }  
245 -  
246 - svg {  
247 - width: 1.2em;  
248 - height: 1.2em;  
249 - }  
250 -  
251 - &__popover-title {  
252 - display: flex;  
253 - align-items: center;  
254 - justify-content: space-between;  
255 - }  
256 -  
257 - &__check-item {  
258 - width: 100%;  
259 - padding: 4px 16px 4px 16px;  
260 -  
261 - .ant-checkbox-wrapper {  
262 - width: 100%;  
263 - }  
264 -  
265 - &:hover {  
266 - background: fade(@primary-color, 10%);  
267 - }  
268 - }  
269 -  
270 - &__cloumn-list {  
271 - .ant-popover-inner-content {  
272 - max-height: 360px;  
273 - padding-right: 0;  
274 - padding-left: 0;  
275 - overflow: auto;  
276 - }  
277 -  
278 - .ant-checkbox-group {  
279 - width: 100%;  
280 - }  
281 - }  
282 - }  
283 -</style>  
src/components/Table/src/components/TableTitle.vue
1 <template> 1 <template>
2 - <BasicTitle class="basic-table-title" v-if="tableTitle" :helpMessage="helpMessage">  
3 - {{ tableTitle }} 2 + <BasicTitle :class="prefixCls" v-if="getTitle" :helpMessage="helpMessage">
  3 + {{ getTitle }}
4 </BasicTitle> 4 </BasicTitle>
5 </template> 5 </template>
6 <script lang="ts"> 6 <script lang="ts">
7 import { computed, defineComponent, PropType } from 'vue'; 7 import { computed, defineComponent, PropType } from 'vue';
8 8
9 import { BasicTitle } from '/@/components/Basic/index'; 9 import { BasicTitle } from '/@/components/Basic/index';
  10 + import { useDesign } from '/@/hooks/web/useDesign';
10 import { isFunction } from '/@/utils/is'; 11 import { isFunction } from '/@/utils/is';
11 export default defineComponent({ 12 export default defineComponent({
12 - name: 'TableTitle', 13 + name: 'BasicTableTitle',
13 components: { BasicTitle }, 14 components: { BasicTitle },
14 props: { 15 props: {
15 title: { 16 title: {
@@ -23,7 +24,9 @@ @@ -23,7 +24,9 @@
23 }, 24 },
24 }, 25 },
25 setup(props) { 26 setup(props) {
26 - const tableTitle = computed(() => { 27 + const { prefixCls } = useDesign('basic-table-title');
  28 +
  29 + const getTitle = computed(() => {
27 const { title, getSelectRows = () => {} } = props; 30 const { title, getSelectRows = () => {} } = props;
28 let tit = title; 31 let tit = title;
29 32
@@ -35,7 +38,16 @@ @@ -35,7 +38,16 @@
35 return tit; 38 return tit;
36 }); 39 });
37 40
38 - return { tableTitle }; 41 + return { getTitle, prefixCls };
39 }, 42 },
40 }); 43 });
41 </script> 44 </script>
  45 +<style lang="less">
  46 + @prefix-cls: ~'@{namespace}-basic-table-title';
  47 +
  48 + .@{prefix-cls} {
  49 + display: flex;
  50 + justify-content: space-between;
  51 + align-items: center;
  52 + }
  53 +</style>
src/components/Table/src/components/renderFooter.tsx deleted 100644 → 0
1 -import { Table } from 'ant-design-vue';  
2 -import { cloneDeep } from 'lodash-es';  
3 -import { unref, ComputedRef } from 'vue';  
4 -import { isFunction } from '/@/utils/is';  
5 -import type { BasicColumn, TableRowSelection } from '../types/table';  
6 -  
7 -export default ({  
8 - scroll = {},  
9 - columnsRef,  
10 - summaryFunc,  
11 - rowKey = 'key',  
12 - dataSourceRef,  
13 - rowSelectionRef,  
14 -}: {  
15 - scroll: { x?: number | true; y?: number };  
16 - columnsRef: ComputedRef<BasicColumn[]>;  
17 - summaryFunc: any;  
18 - rowKey?: string;  
19 - dataSourceRef: ComputedRef<any[]>;  
20 - rowSelectionRef: ComputedRef<TableRowSelection | null>;  
21 -}) => {  
22 - if (!summaryFunc) {  
23 - return;  
24 - }  
25 - const dataSource: any[] = isFunction(summaryFunc) ? summaryFunc(unref(dataSourceRef)) : [];  
26 - const columns: BasicColumn[] = cloneDeep(unref(columnsRef));  
27 - const index = columns.findIndex((item) => item.flag === 'INDEX');  
28 - const hasRowSummary = dataSource.some((item) => Reflect.has(item, '_row'));  
29 - const hasIndexSummary = dataSource.some((item) => Reflect.has(item, '_index'));  
30 -  
31 - if (index !== -1) {  
32 - if (hasIndexSummary) {  
33 - columns[index].customRender = ({ record }) => record._index;  
34 - columns[index].ellipsis = false;  
35 - } else {  
36 - Reflect.deleteProperty(columns[index], 'customRender');  
37 - }  
38 - }  
39 - if (unref(rowSelectionRef) && hasRowSummary) {  
40 - columns.unshift({  
41 - width: 60,  
42 - title: 'selection',  
43 - key: 'selectionKey',  
44 - align: 'center',  
45 - customRender: ({ record }) => record._row,  
46 - });  
47 - }  
48 -  
49 - dataSource.forEach((item, i) => {  
50 - item[rowKey] = i;  
51 - });  
52 - return (  
53 - <Table  
54 - showHeader={false}  
55 - bordered={false}  
56 - pagination={false}  
57 - dataSource={dataSource}  
58 - rowKey={rowKey}  
59 - columns={columns}  
60 - tableLayout="fixed"  
61 - scroll={scroll as any}  
62 - />  
63 - );  
64 -};  
src/components/Table/src/components/renderTitle.tsx deleted 100644 → 0
1 -import { Slots } from 'vue';  
2 -import TableTitle from './TableTitle.vue';  
3 -import { getSlot } from '/@/utils/helper/tsxHelper';  
4 -import TableSettingComp from './TableSetting.vue';  
5 -  
6 -import type { TableSetting } from '../types/table';  
7 -  
8 -export default (  
9 - title: any,  
10 - titleHelpMessage: string | string[],  
11 - slots: Slots,  
12 - showTableSetting: boolean,  
13 - tableSetting: TableSetting  
14 -) => {  
15 - return (  
16 - <>  
17 - {getSlot(slots, 'tableTitle') ||  
18 - (title && <TableTitle helpMessage={titleHelpMessage} title={title} />) || (  
19 - <span>&nbsp;</span>  
20 - )}  
21 - {  
22 - <div class="basic-table-toolbar">  
23 - {slots.toolbar && getSlot(slots, 'toolbar')}  
24 - {showTableSetting && <TableSettingComp setting={tableSetting} />}  
25 - </div>  
26 - }  
27 - </>  
28 - );  
29 -};  
src/components/Table/src/components/settings/ColumnSetting.vue 0 → 100644
  1 +<template>
  2 + <Tooltip placement="top">
  3 + <template #title>
  4 + <span>{{ t('component.table.settingColumn') }}</span>
  5 + </template>
  6 + <Popover
  7 + :getPopupContainer="getPopupContainer"
  8 + placement="bottomLeft"
  9 + trigger="click"
  10 + @visibleChange="handleVisibleChange"
  11 + :overlayClassName="`${prefixCls}__cloumn-list`"
  12 + >
  13 + <template #title>
  14 + <div :class="`${prefixCls}__popover-title`">
  15 + <Checkbox
  16 + :indeterminate="indeterminate"
  17 + v-model:checked="checkAll"
  18 + @change="onCheckAllChange"
  19 + >
  20 + {{ t('component.table.settingColumnShow') }}
  21 + </Checkbox>
  22 +
  23 + <Checkbox v-model:checked="checkIndex" @change="handleIndexCheckChange">
  24 + {{ t('component.table.settingIndexColumnShow') }}
  25 + </Checkbox>
  26 +
  27 + <Checkbox
  28 + v-model:checked="checkSelect"
  29 + @change="handleSelectCheckChange"
  30 + :disabled="!defaultRowSelection"
  31 + >
  32 + {{ t('component.table.settingSelectColumnShow') }}
  33 + </Checkbox>
  34 +
  35 + <a-button size="small" type="link" @click="reset">
  36 + {{ t('component.table.settingReset') }}
  37 + </a-button>
  38 + </div>
  39 + </template>
  40 +
  41 + <template #content>
  42 + <ScrollContainer>
  43 + <CheckboxGroup v-model:value="checkedList" @change="onChange" ref="columnListRef">
  44 + <template v-for="item in plainOptions" :key="item.value">
  45 + <div :class="`${prefixCls}__check-item`">
  46 + <DragOutlined class="table-coulmn-drag-icon" />
  47 + <Checkbox :value="item.value"> {{ item.label }} </Checkbox>
  48 +
  49 + <Tooltip placement="bottomLeft" :mouseLeaveDelay="0.4">
  50 + <template #title> {{ t('component.table.settingFixedLeft') }}</template>
  51 + <Icon
  52 + icon="line-md:arrow-align-left"
  53 + :class="[
  54 + `${prefixCls}__fixed-left`,
  55 + {
  56 + active: item.fixed === 'left',
  57 + disabled: !checkedList.includes(item.value),
  58 + },
  59 + ]"
  60 + @click="handleColumnFixed(item, 'left')"
  61 + />
  62 + </Tooltip>
  63 + <Divider type="vertical" />
  64 + <Tooltip placement="bottomLeft" :mouseLeaveDelay="0.4">
  65 + <template #title> {{ t('component.table.settingFixedRight') }}</template>
  66 + <Icon
  67 + icon="line-md:arrow-align-left"
  68 + :class="[
  69 + `${prefixCls}__fixed-right`,
  70 + {
  71 + active: item.fixed === 'right',
  72 + disabled: !checkedList.includes(item.value),
  73 + },
  74 + ]"
  75 + @click="handleColumnFixed(item, 'right')"
  76 + />
  77 + </Tooltip>
  78 + </div>
  79 + </template>
  80 + </CheckboxGroup>
  81 + </ScrollContainer>
  82 + </template>
  83 + <SettingOutlined />
  84 + </Popover>
  85 + </Tooltip>
  86 +</template>
  87 +<script lang="ts">
  88 + import {
  89 + defineComponent,
  90 + ref,
  91 + reactive,
  92 + toRefs,
  93 + watchEffect,
  94 + nextTick,
  95 + unref,
  96 + computed,
  97 + } from 'vue';
  98 + import { Tooltip, Popover, Checkbox, Divider } from 'ant-design-vue';
  99 + import { SettingOutlined, DragOutlined } from '@ant-design/icons-vue';
  100 + import { Icon } from '/@/components/Icon';
  101 + import { ScrollContainer } from '/@/components/Container';
  102 +
  103 + import { useI18n } from '/@/hooks/web/useI18n';
  104 + import { useTableContext } from '../../hooks/useTableContext';
  105 + import { useDesign } from '/@/hooks/web/useDesign';
  106 + import { useSortable } from '/@/hooks/web/useSortable';
  107 +
  108 + import { isNullAndUnDef } from '/@/utils/is';
  109 + import { getPopupContainer } from '/@/utils';
  110 +
  111 + import type { BasicColumn } from '../../types/table';
  112 +
  113 + interface State {
  114 + indeterminate: boolean;
  115 + checkAll: boolean;
  116 + checkedList: string[];
  117 + defaultCheckList: string[];
  118 + }
  119 +
  120 + interface Options {
  121 + label: string;
  122 + value: string;
  123 + fixed?: boolean | 'left' | 'right';
  124 + }
  125 +
  126 + export default defineComponent({
  127 + name: 'ColumnSetting',
  128 + components: {
  129 + SettingOutlined,
  130 + Popover,
  131 + Tooltip,
  132 + Checkbox,
  133 + CheckboxGroup: Checkbox.Group,
  134 + DragOutlined,
  135 + ScrollContainer,
  136 + Divider,
  137 + Icon,
  138 + },
  139 +
  140 + setup() {
  141 + const { t } = useI18n();
  142 + const table = useTableContext();
  143 +
  144 + const defaultRowSelection = table.getRowSelection();
  145 + let inited = false;
  146 +
  147 + const cachePlainOptions = ref<Options[]>([]);
  148 + const plainOptions = ref<Options[]>([]);
  149 +
  150 + const plainSortOptions = ref<Options[]>([]);
  151 +
  152 + const columnListRef = ref<ComponentRef>(null);
  153 +
  154 + const state = reactive<State>({
  155 + indeterminate: false,
  156 + checkAll: true,
  157 + checkedList: [],
  158 + defaultCheckList: [],
  159 + });
  160 +
  161 + const checkIndex = ref(false);
  162 + const checkSelect = ref(false);
  163 +
  164 + const { prefixCls } = useDesign('basic-column-setting');
  165 +
  166 + const getValues = computed(() => {
  167 + return unref(table?.getBindValues) || {};
  168 + });
  169 +
  170 + watchEffect(() => {
  171 + const columns = table.getColumns();
  172 + if (columns.length) {
  173 + init();
  174 + }
  175 + });
  176 +
  177 + watchEffect(() => {
  178 + const values = unref(getValues);
  179 + checkIndex.value = !!values.showIndexColumn;
  180 + checkSelect.value = !!values.rowSelection;
  181 + });
  182 +
  183 + function getColumns() {
  184 + const ret: Options[] = [];
  185 + table.getColumns({ ignoreIndex: true, ignoreAction: true }).forEach((item) => {
  186 + ret.push({
  187 + label: item.title as string,
  188 + value: (item.dataIndex || item.title) as string,
  189 + ...item,
  190 + });
  191 + });
  192 + return ret;
  193 + }
  194 +
  195 + function init() {
  196 + const columns = getColumns();
  197 +
  198 + const checkList = table
  199 + .getColumns()
  200 + .map((item) => {
  201 + if (item.defaultHidden) {
  202 + return '';
  203 + }
  204 + return item.dataIndex || item.title;
  205 + })
  206 + .filter(Boolean) as string[];
  207 +
  208 + if (!plainOptions.value.length) {
  209 + plainOptions.value = columns;
  210 + plainSortOptions.value = columns;
  211 + cachePlainOptions.value = columns;
  212 + state.defaultCheckList = checkList;
  213 + } else {
  214 + const fixedColumns = columns.filter((item) =>
  215 + Reflect.has(item, 'fixed')
  216 + ) as BasicColumn[];
  217 +
  218 + unref(plainOptions).forEach((item: BasicColumn) => {
  219 + const findItem = fixedColumns.find((fCol) => fCol.dataIndex === item.dataIndex);
  220 + if (findItem) {
  221 + item.fixed = findItem.fixed;
  222 + }
  223 + });
  224 + }
  225 +
  226 + state.checkedList = checkList;
  227 + }
  228 +
  229 + // checkAll change
  230 + function onCheckAllChange(e: ChangeEvent) {
  231 + state.indeterminate = false;
  232 + const checkList = plainOptions.value.map((item) => item.value);
  233 + if (e.target.checked) {
  234 + state.checkedList = checkList;
  235 + table.setColumns(checkList);
  236 + } else {
  237 + state.checkedList = [];
  238 + table.setColumns([]);
  239 + }
  240 + }
  241 +
  242 + // Trigger when check/uncheck a column
  243 + function onChange(checkedList: string[]) {
  244 + const len = plainOptions.value.length;
  245 + state.indeterminate = !!checkedList.length && checkedList.length < len;
  246 + state.checkAll = checkedList.length === len;
  247 +
  248 + const sortList = unref(plainSortOptions).map((item) => item.value);
  249 + checkedList.sort((prev, next) => {
  250 + return sortList.indexOf(prev) - sortList.indexOf(next);
  251 + });
  252 + table.setColumns(checkedList);
  253 + }
  254 +
  255 + // reset columns
  256 + function reset() {
  257 + state.checkedList = [...state.defaultCheckList];
  258 + state.checkAll = true;
  259 + state.indeterminate = false;
  260 + plainOptions.value = unref(cachePlainOptions);
  261 + plainSortOptions.value = unref(cachePlainOptions);
  262 + table.setColumns(table.getCacheColumns());
  263 + }
  264 +
  265 + // Open the pop-up window for drag and drop initialization
  266 + function handleVisibleChange() {
  267 + if (inited) return;
  268 + nextTick(() => {
  269 + const columnListEl = unref(columnListRef);
  270 + if (!columnListEl) return;
  271 + const el = columnListEl.$el;
  272 + if (!el) return;
  273 + // Drag and drop sort
  274 + const { initSortable } = useSortable(el, {
  275 + handle: '.table-coulmn-drag-icon ',
  276 + onEnd: (evt) => {
  277 + const { oldIndex, newIndex } = evt;
  278 + if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
  279 + return;
  280 + }
  281 + // Sort column
  282 + const columns = getColumns();
  283 +
  284 + if (oldIndex > newIndex) {
  285 + columns.splice(newIndex, 0, columns[oldIndex]);
  286 + columns.splice(oldIndex + 1, 1);
  287 + } else {
  288 + columns.splice(newIndex + 1, 0, columns[oldIndex]);
  289 + columns.splice(oldIndex, 1);
  290 + }
  291 +
  292 + plainSortOptions.value = columns;
  293 + plainOptions.value = columns;
  294 + table.setColumns(columns);
  295 + },
  296 + });
  297 + initSortable();
  298 + inited = true;
  299 + });
  300 + }
  301 +
  302 + // Control whether the serial number column is displayed
  303 + function handleIndexCheckChange(e: ChangeEvent) {
  304 + table.setProps({
  305 + showIndexColumn: e.target.checked,
  306 + });
  307 + }
  308 +
  309 + // Control whether the check box is displayed
  310 + function handleSelectCheckChange(e: ChangeEvent) {
  311 + table.setProps({
  312 + rowSelection: e.target.checked ? defaultRowSelection : undefined,
  313 + });
  314 + }
  315 +
  316 + function handleColumnFixed(item: BasicColumn, fixed?: 'left' | 'right') {
  317 + if (!state.checkedList.includes(item.dataIndex as string)) return;
  318 +
  319 + const columns = getColumns() as BasicColumn[];
  320 + const isFixed = item.fixed === fixed ? false : fixed;
  321 + const index = columns.findIndex((col) => col.dataIndex === item.dataIndex);
  322 + if (index !== -1) {
  323 + columns[index].fixed = isFixed;
  324 + }
  325 + item.fixed = isFixed;
  326 +
  327 + if (isFixed && !item.width) {
  328 + item.width = 100;
  329 + }
  330 +
  331 + table.setColumns(columns);
  332 + }
  333 +
  334 + return {
  335 + t,
  336 + ...toRefs(state),
  337 + onCheckAllChange,
  338 + onChange,
  339 + plainOptions,
  340 + reset,
  341 + prefixCls,
  342 + columnListRef,
  343 + handleVisibleChange,
  344 + checkIndex,
  345 + checkSelect,
  346 + handleIndexCheckChange,
  347 + handleSelectCheckChange,
  348 + defaultRowSelection,
  349 + handleColumnFixed,
  350 + getPopupContainer,
  351 + };
  352 + },
  353 + });
  354 +</script>
  355 +<style lang="less">
  356 + @prefix-cls: ~'@{namespace}-basic-column-setting';
  357 +
  358 + .table-coulmn-drag-icon {
  359 + margin: 0 5px;
  360 + cursor: move;
  361 + }
  362 +
  363 + .@{prefix-cls} {
  364 + &__popover-title {
  365 + position: relative;
  366 + display: flex;
  367 + align-items: center;
  368 + justify-content: space-between;
  369 + }
  370 +
  371 + &__check-item {
  372 + display: flex;
  373 + align-items: center;
  374 + min-width: 100%;
  375 + padding: 4px 16px 8px 0;
  376 +
  377 + .ant-checkbox-wrapper {
  378 + width: 100%;
  379 +
  380 + &:hover {
  381 + color: @primary-color;
  382 + }
  383 + }
  384 + }
  385 +
  386 + &__fixed-left,
  387 + &__fixed-right {
  388 + color: rgba(0, 0, 0, 0.45);
  389 + cursor: pointer;
  390 +
  391 + &.active,
  392 + &:hover {
  393 + color: @primary-color;
  394 + }
  395 +
  396 + &.disabled {
  397 + color: @disabled-color;
  398 + cursor: not-allowed;
  399 + }
  400 + }
  401 +
  402 + &__fixed-right {
  403 + transform: rotate(180deg);
  404 + }
  405 +
  406 + &__cloumn-list {
  407 + svg {
  408 + width: 1em !important;
  409 + height: 1em !important;
  410 + }
  411 +
  412 + .ant-popover-inner-content {
  413 + // max-height: 360px;
  414 + padding-right: 0;
  415 + padding-left: 0;
  416 + // overflow: auto;
  417 + }
  418 +
  419 + .ant-checkbox-group {
  420 + width: 100%;
  421 + min-width: 260px;
  422 + // flex-wrap: wrap;
  423 + }
  424 +
  425 + .scroll-container {
  426 + height: 220px;
  427 + }
  428 + }
  429 + }
  430 +</style>
src/components/Table/src/components/settings/FullScreenSetting.vue 0 → 100644
  1 +<template>
  2 + <Tooltip placement="top">
  3 + <template #title>
  4 + <span>{{ t('component.table.settingFullScreen') }}</span>
  5 + </template>
  6 + <FullscreenOutlined @click="handleFullScreen" v-if="!isFullscreenRef" />
  7 + <FullscreenExitOutlined @click="handleFullScreen" v-else />
  8 + </Tooltip>
  9 +</template>
  10 +<script lang="ts">
  11 + import { defineComponent } from 'vue';
  12 + import { useTableContext } from '../../hooks/useTableContext';
  13 + import { Tooltip } from 'ant-design-vue';
  14 + import { FullscreenOutlined, FullscreenExitOutlined } from '@ant-design/icons-vue';
  15 + import { useFullscreen } from '/@/hooks/web/useFullScreen';
  16 + import { useI18n } from '/@/hooks/web/useI18n';
  17 +
  18 + export default defineComponent({
  19 + name: 'FullScreenSetting',
  20 + components: {
  21 + FullscreenExitOutlined,
  22 + FullscreenOutlined,
  23 + Tooltip,
  24 + },
  25 +
  26 + setup() {
  27 + const table = useTableContext();
  28 + const { t } = useI18n();
  29 +
  30 + const { toggleFullscreen, isFullscreenRef } = useFullscreen(table.wrapRef);
  31 +
  32 + function handleFullScreen() {
  33 + toggleFullscreen();
  34 + }
  35 +
  36 + return {
  37 + handleFullScreen,
  38 + isFullscreenRef,
  39 + t,
  40 + };
  41 + },
  42 + });
  43 +</script>
src/components/Table/src/components/settings/RedoSetting.vue 0 → 100644
  1 +<template>
  2 + <Tooltip placement="top">
  3 + <template #title>
  4 + <span>{{ t('component.table.settingRedo') }}</span>
  5 + </template>
  6 + <RedoOutlined @click="redo" />
  7 + </Tooltip>
  8 +</template>
  9 +<script lang="ts">
  10 + import { defineComponent } from 'vue';
  11 + import { useTableContext } from '../../hooks/useTableContext';
  12 + import { Tooltip } from 'ant-design-vue';
  13 + import { RedoOutlined } from '@ant-design/icons-vue';
  14 + import { useI18n } from '/@/hooks/web/useI18n';
  15 +
  16 + export default defineComponent({
  17 + name: 'RedoSetting',
  18 + components: {
  19 + RedoOutlined,
  20 + Tooltip,
  21 + },
  22 +
  23 + setup() {
  24 + const table = useTableContext();
  25 + const { t } = useI18n();
  26 +
  27 + function redo() {
  28 + table.reload();
  29 + }
  30 +
  31 + return {
  32 + redo,
  33 + t,
  34 + };
  35 + },
  36 + });
  37 +</script>
src/components/Table/src/components/settings/SizeSetting.vue 0 → 100644
  1 +<template>
  2 + <Tooltip placement="top">
  3 + <template #title>
  4 + <span>{{ t('component.table.settingDens') }}</span>
  5 + </template>
  6 +
  7 + <Dropdown placement="bottomCenter" :trigger="['click']" :getPopupContainer="getPopupContainer">
  8 + <ColumnHeightOutlined />
  9 + <template #overlay>
  10 + <Menu @click="handleTitleClick" selectable v-model:selectedKeys="selectedKeysRef">
  11 + <MenuItem key="default">
  12 + <span>{{ t('component.table.settingDensDefault') }}</span>
  13 + </MenuItem>
  14 + <MenuItem key="middle">
  15 + <span>{{ t('component.table.settingDensMiddle') }}</span>
  16 + </MenuItem>
  17 + <MenuItem key="small">
  18 + <span>{{ t('component.table.settingDensSmall') }}</span>
  19 + </MenuItem>
  20 + </Menu>
  21 + </template>
  22 + </Dropdown>
  23 + </Tooltip>
  24 +</template>
  25 +<script lang="ts">
  26 + import { defineComponent, ref } from 'vue';
  27 + import { useTableContext } from '../../hooks/useTableContext';
  28 + import { Tooltip, Dropdown, Menu } from 'ant-design-vue';
  29 + import { ColumnHeightOutlined } from '@ant-design/icons-vue';
  30 + import { useI18n } from '/@/hooks/web/useI18n';
  31 + import { getPopupContainer } from '/@/utils';
  32 +
  33 + import type { SizeType } from '../../types/table';
  34 +
  35 + export default defineComponent({
  36 + name: 'SizeSetting',
  37 + components: {
  38 + ColumnHeightOutlined,
  39 + Tooltip,
  40 + Dropdown,
  41 + Menu,
  42 + MenuItem: Menu.Item,
  43 + },
  44 + setup() {
  45 + const table = useTableContext();
  46 + const { t } = useI18n();
  47 +
  48 + const selectedKeysRef = ref<SizeType[]>([table.getSize()]);
  49 +
  50 + function handleTitleClick({ key }: { key: SizeType }) {
  51 + selectedKeysRef.value = [key];
  52 + table.setProps({
  53 + size: key,
  54 + });
  55 + }
  56 +
  57 + return {
  58 + handleTitleClick,
  59 + selectedKeysRef,
  60 + getPopupContainer,
  61 + t,
  62 + };
  63 + },
  64 + });
  65 +</script>
src/components/Table/src/components/settings/index.vue 0 → 100644
  1 +<template>
  2 + <div class="table-settings">
  3 + <RedoSetting v-if="getSetting.size" />
  4 + <SizeSetting v-if="getSetting.redo" />
  5 +
  6 + <ColumnSetting v-if="getSetting.setting" />
  7 +
  8 + <FullScreenSetting v-if="getSetting.fullScreen" />
  9 + </div>
  10 +</template>
  11 +<script lang="ts">
  12 + import { defineComponent, PropType, computed } from 'vue';
  13 + import type { TableSetting } from '../../types/table';
  14 + import { useI18n } from '/@/hooks/web/useI18n';
  15 + import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  16 + import ColumnSetting from './ColumnSetting.vue';
  17 + export default defineComponent({
  18 + name: 'TableSetting',
  19 + components: {
  20 + ColumnSetting,
  21 + SizeSetting: createAsyncComponent(() => import('./SizeSetting.vue')),
  22 + RedoSetting: createAsyncComponent(() => import('./RedoSetting.vue')),
  23 + FullScreenSetting: createAsyncComponent(() => import('./FullScreenSetting.vue')),
  24 + },
  25 + props: {
  26 + setting: {
  27 + type: Object as PropType<TableSetting>,
  28 + default: {},
  29 + },
  30 + },
  31 + setup(props) {
  32 + const { t } = useI18n();
  33 +
  34 + const getSetting = computed(
  35 + (): TableSetting => {
  36 + return {
  37 + redo: true,
  38 + size: true,
  39 + setting: true,
  40 + fullScreen: true,
  41 + ...props.setting,
  42 + };
  43 + }
  44 + );
  45 +
  46 + return { getSetting, t };
  47 + },
  48 + });
  49 +</script>
  50 +<style lang="less">
  51 + .table-settings {
  52 + & > * {
  53 + margin-right: 12px;
  54 + }
  55 +
  56 + svg {
  57 + width: 1.3em;
  58 + height: 1.3em;
  59 + }
  60 + }
  61 +</style>
src/components/Table/src/hooks/useColumns.ts
1 import { BasicColumn, BasicTableProps, GetColumnsParams } from '../types/table'; 1 import { BasicColumn, BasicTableProps, GetColumnsParams } from '../types/table';
2 import { PaginationProps } from '../types/pagination'; 2 import { PaginationProps } from '../types/pagination';
3 import { unref, ComputedRef, Ref, computed, watchEffect, ref, toRaw } from 'vue'; 3 import { unref, ComputedRef, Ref, computed, watchEffect, ref, toRaw } from 'vue';
4 -import { isBoolean, isArray, isObject } from '/@/utils/is'; 4 +import { isBoolean, isArray, isString } from '/@/utils/is';
5 import { DEFAULT_ALIGN, PAGE_SIZE, INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG } from '../const'; 5 import { DEFAULT_ALIGN, PAGE_SIZE, INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG } from '../const';
6 import { useI18n } from '/@/hooks/web/useI18n'; 6 import { useI18n } from '/@/hooks/web/useI18n';
  7 +import { isEqual, cloneDeep } from 'lodash-es';
7 8
8 const { t } = useI18n(); 9 const { t } = useI18n();
9 10
@@ -107,27 +108,31 @@ export function useColumns( @@ -107,27 +108,31 @@ export function useColumns(
107 108
108 const getColumnsRef = computed(() => { 109 const getColumnsRef = computed(() => {
109 const columns = unref(columnsRef); 110 const columns = unref(columnsRef);
110 - if (!columns) {  
111 - return [];  
112 - }  
113 111
114 handleIndexColumn(propsRef, getPaginationRef, columns); 112 handleIndexColumn(propsRef, getPaginationRef, columns);
115 handleActionColumn(propsRef, columns); 113 handleActionColumn(propsRef, columns);
116 - 114 + if (!columns) {
  115 + return [];
  116 + }
117 return columns; 117 return columns;
118 }); 118 });
119 119
  120 + const getSortFixedColumns = computed(() => {
  121 + return useFixedColumn(unref(getColumnsRef));
  122 + });
  123 +
120 watchEffect(() => { 124 watchEffect(() => {
121 const columns = toRaw(unref(propsRef).columns); 125 const columns = toRaw(unref(propsRef).columns);
122 columnsRef.value = columns; 126 columnsRef.value = columns;
123 - cacheColumns = columns; 127 + cacheColumns = columns?.filter((item) => !item.flag) ?? [];
124 }); 128 });
125 129
126 /** 130 /**
127 * set columns 131 * set columns
128 - * @param columns key|column 132 + * @param columnList key|column
129 */ 133 */
130 - function setColumns(columns: Partial<BasicColumn>[] | string[]) { 134 + function setColumns(columnList: Partial<BasicColumn>[] | string[]) {
  135 + const columns = cloneDeep(columnList);
131 if (!isArray(columns)) return; 136 if (!isArray(columns)) return;
132 137
133 if (columns.length <= 0) { 138 if (columns.length <= 0) {
@@ -137,20 +142,36 @@ export function useColumns( @@ -137,20 +142,36 @@ export function useColumns(
137 142
138 const firstColumn = columns[0]; 143 const firstColumn = columns[0];
139 144
140 - if (isObject(firstColumn)) { 145 + const cacheKeys = cacheColumns.map((item) => item.dataIndex);
  146 +
  147 + if (!isString(firstColumn)) {
141 columnsRef.value = columns as BasicColumn[]; 148 columnsRef.value = columns as BasicColumn[];
142 } else { 149 } else {
143 - const newColumns = cacheColumns.filter(  
144 - (item) =>  
145 - (item.dataIndex || `${item.key}`) &&  
146 - (columns as string[]).includes(`${item.key}`! || item.dataIndex!)  
147 - ); 150 + const columnKeys = columns as string[];
  151 + const newColumns: BasicColumn[] = [];
  152 + cacheColumns.forEach((item) => {
  153 + if (columnKeys.includes(`${item.key}`! || item.dataIndex!)) {
  154 + newColumns.push({
  155 + ...item,
  156 + defaultHidden: false,
  157 + });
  158 + }
  159 + });
  160 + // Sort according to another array
  161 + if (!isEqual(cacheKeys, columns)) {
  162 + newColumns.sort((prev, next) => {
  163 + return (
  164 + columnKeys.indexOf(prev.dataIndex as string) -
  165 + columnKeys.indexOf(next.dataIndex as string)
  166 + );
  167 + });
  168 + }
148 columnsRef.value = newColumns; 169 columnsRef.value = newColumns;
149 } 170 }
150 } 171 }
151 172
152 function getColumns(opt?: GetColumnsParams) { 173 function getColumns(opt?: GetColumnsParams) {
153 - const { ignoreIndex, ignoreAction } = opt || {}; 174 + const { ignoreIndex, ignoreAction, sort } = opt || {};
154 let columns = toRaw(unref(getColumnsRef)); 175 let columns = toRaw(unref(getColumnsRef));
155 if (ignoreIndex) { 176 if (ignoreIndex) {
156 columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG); 177 columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG);
@@ -158,8 +179,38 @@ export function useColumns( @@ -158,8 +179,38 @@ export function useColumns(
158 if (ignoreAction) { 179 if (ignoreAction) {
159 columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG); 180 columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG);
160 } 181 }
  182 +
  183 + if (sort) {
  184 + columns = useFixedColumn(columns);
  185 + }
  186 +
161 return columns; 187 return columns;
162 } 188 }
  189 + function getCacheColumns() {
  190 + return cacheColumns;
  191 + }
  192 +
  193 + return { getColumnsRef, getCacheColumns, getColumns, setColumns, getSortFixedColumns };
  194 +}
  195 +
  196 +export function useFixedColumn(columns: BasicColumn[]) {
  197 + const fixedLeftColumns: BasicColumn[] = [];
  198 + const fixedRightColumns: BasicColumn[] = [];
  199 + const defColumns: BasicColumn[] = [];
  200 + for (const column of columns) {
  201 + if (column.fixed === 'left') {
  202 + fixedLeftColumns.push(column);
  203 + continue;
  204 + }
  205 + if (column.fixed === 'right') {
  206 + fixedRightColumns.push(column);
  207 + continue;
  208 + }
  209 + defColumns.push(column);
  210 + }
  211 + const resultColumns = [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter(
  212 + (item) => !item.defaultHidden
  213 + );
163 214
164 - return { getColumnsRef, getColumns, setColumns }; 215 + return resultColumns;
165 } 216 }
src/components/Table/src/hooks/useRowSelection.ts
@@ -53,7 +53,12 @@ export function useRowSelection(propsRef: ComputedRef&lt;BasicTableProps&gt;, emit: Em @@ -53,7 +53,12 @@ export function useRowSelection(propsRef: ComputedRef&lt;BasicTableProps&gt;, emit: Em
53 return unref(selectedRowRef) as T[]; 53 return unref(selectedRowRef) as T[];
54 } 54 }
55 55
  56 + function getRowSelection() {
  57 + return unref(getRowSelectionRef)!;
  58 + }
  59 +
56 return { 60 return {
  61 + getRowSelection,
57 getRowSelectionRef, 62 getRowSelectionRef,
58 getSelectRows, 63 getSelectRows,
59 getSelectRowKeys, 64 getSelectRowKeys,
src/components/Table/src/hooks/useTableContext.ts 0 → 100644
  1 +import type { Ref } from 'vue';
  2 +import type { BasicTableProps, TableActionType } from '../types/table';
  3 +
  4 +import { provide, inject, ComputedRef } from 'vue';
  5 +
  6 +const key = Symbol('basic-table');
  7 +
  8 +type Instance = TableActionType & {
  9 + wrapRef: Ref<Nullable<HTMLElement>>;
  10 + getBindValues: ComputedRef<Recordable>;
  11 +};
  12 +
  13 +type RetInstance = Omit<Instance, 'getBindValues'> & {
  14 + getBindValues: ComputedRef<BasicTableProps>;
  15 +};
  16 +
  17 +export function createTableContext(instance: Instance) {
  18 + provide(key, instance);
  19 +}
  20 +
  21 +export function useTableContext(): RetInstance {
  22 + return inject(key) as RetInstance;
  23 +}
src/components/Table/src/hooks/useTableFooter.ts 0 → 100644
  1 +import type { ComputedRef, Ref } from 'vue';
  2 +import type { BasicTableProps } from '../types/table';
  3 +import { unref, computed, h, nextTick, watchEffect } from 'vue';
  4 +import TableFooter from '../components/TableFooter.vue';
  5 +import { useEventListener } from '/@/hooks/event/useEventListener';
  6 +
  7 +export function useTableFooter(
  8 + propsRef: ComputedRef<BasicTableProps>,
  9 + scrollRef: ComputedRef<{
  10 + x: string | number | true;
  11 + y: Nullable<number>;
  12 + scrollToFirstRowOnChange: boolean;
  13 + }>,
  14 + tableElRef: Ref<ComponentRef>,
  15 + getDataSourceRef: ComputedRef<Recordable>
  16 +) {
  17 + const getIsEmptyData = computed(() => {
  18 + return (unref(getDataSourceRef) || []).length === 0;
  19 + });
  20 +
  21 + const getFooterProps = computed((): Recordable | undefined => {
  22 + const { summaryFunc, showSummary } = unref(propsRef);
  23 + return showSummary && !unref(getIsEmptyData)
  24 + ? () => h(TableFooter, { summaryFunc, scroll: unref(scrollRef) })
  25 + : undefined;
  26 + });
  27 +
  28 + watchEffect(() => {
  29 + handleSummary();
  30 + });
  31 +
  32 + function handleSummary() {
  33 + const { showSummary } = unref(propsRef);
  34 + if (!showSummary || unref(getIsEmptyData)) return;
  35 +
  36 + nextTick(() => {
  37 + const tableEl = unref(tableElRef);
  38 + if (!tableEl) return;
  39 + const bodyDomList = tableEl.$el.querySelectorAll('.ant-table-body');
  40 + const bodyDom = bodyDomList[0];
  41 + useEventListener({
  42 + el: bodyDom,
  43 + name: 'scroll',
  44 + listener: () => {
  45 + const footerBodyDom = tableEl.$el.querySelector(
  46 + '.ant-table-footer .ant-table-body'
  47 + ) as HTMLDivElement;
  48 + if (!footerBodyDom || !bodyDom) return;
  49 + footerBodyDom.scrollLeft = bodyDom.scrollLeft;
  50 + },
  51 + wait: 0,
  52 + options: true,
  53 + });
  54 + });
  55 + }
  56 + return { getFooterProps };
  57 +}
src/components/Table/src/hooks/useTableForm.ts 0 → 100644
  1 +import type { ComputedRef, Slots } from 'vue';
  2 +import type { BasicTableProps, FetchParams } from '../types/table';
  3 +import { unref, computed } from 'vue';
  4 +import type { FormProps } from '/@/components/Form';
  5 +import { isFunction } from '/@/utils/is';
  6 +export function useTableForm(
  7 + propsRef: ComputedRef<BasicTableProps>,
  8 + slots: Slots,
  9 + fetch: (opt?: FetchParams | undefined) => Promise<void>
  10 +) {
  11 + const getFormProps = computed(
  12 + (): Partial<FormProps> => {
  13 + const { formConfig } = unref(propsRef);
  14 + return {
  15 + showAdvancedButton: true,
  16 + ...formConfig,
  17 + compact: true,
  18 + };
  19 + }
  20 + );
  21 +
  22 + const getFormSlotKeys = computed(() => {
  23 + const keys = Object.keys(slots);
  24 + return keys.map((item) => (item.startsWith('form-') ? item : null)).filter(Boolean);
  25 + });
  26 +
  27 + function replaceFormSlotKey(key: string) {
  28 + if (!key) return '';
  29 + return key?.replace?.(/form\-/, '') ?? '';
  30 + }
  31 +
  32 + function handleSearchInfoChange(info: Recordable) {
  33 + const { handleSearchInfoFn } = unref(propsRef);
  34 + if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) {
  35 + info = handleSearchInfoFn(info) || info;
  36 + }
  37 + fetch({ searchInfo: info, page: 1 });
  38 + }
  39 +
  40 + return {
  41 + getFormProps,
  42 + replaceFormSlotKey,
  43 + getFormSlotKeys,
  44 + handleSearchInfoChange,
  45 + };
  46 +}
src/components/Table/src/hooks/useTableHeader.ts 0 → 100644
  1 +import type { ComputedRef, Slots } from 'vue';
  2 +import type { BasicTableProps } from '../types/table';
  3 +import { unref, computed, h } from 'vue';
  4 +import { isString } from '/@/utils/is';
  5 +import TableHeader from '../components/TableHeader.vue';
  6 +import { getSlot } from '../../../../utils/helper/tsxHelper';
  7 +
  8 +export function useTableHeader(propsRef: ComputedRef<BasicTableProps>, slots: Slots) {
  9 + const getHeaderProps = computed(
  10 + (): Recordable => {
  11 + const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(propsRef);
  12 + const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting;
  13 + if (hideTitle && !isString(title)) {
  14 + return {};
  15 + }
  16 +
  17 + return {
  18 + title: hideTitle
  19 + ? null
  20 + : () =>
  21 + h(
  22 + TableHeader,
  23 + {
  24 + title,
  25 + titleHelpMessage,
  26 + showTableSetting,
  27 + tableSetting,
  28 + },
  29 + {
  30 + ...(slots.toolbar
  31 + ? {
  32 + toolbar: () => getSlot(slots, 'toolbar'),
  33 + }
  34 + : {}),
  35 + ...(slots.tableTitle
  36 + ? {
  37 + tableTitle: () => getSlot(slots, 'tableTitle'),
  38 + }
  39 + : {}),
  40 + }
  41 + ),
  42 + };
  43 + }
  44 + );
  45 + return { getHeaderProps };
  46 +}
src/components/Table/src/hooks/useTableScroll.ts
1 -import type { BasicTableProps } from '../types/table'; 1 +import type { BasicTableProps, TableRowSelection } from '../types/table';
2 import type { Ref, ComputedRef } from 'vue'; 2 import type { Ref, ComputedRef } from 'vue';
3 import { computed, unref, ref, nextTick, watchEffect } from 'vue'; 3 import { computed, unref, ref, nextTick, watchEffect } from 'vue';
4 4
@@ -7,22 +7,29 @@ import { isBoolean } from &#39;/@/utils/is&#39;; @@ -7,22 +7,29 @@ import { isBoolean } from &#39;/@/utils/is&#39;;
7 7
8 import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; 8 import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
9 import { useModalContext } from '/@/components/Modal'; 9 import { useModalContext } from '/@/components/Modal';
  10 +import { useDebounce } from '/@/hooks/core/useDebounce';
  11 +import type { BasicColumn } from '/@/components/Table';
10 12
11 export function useTableScroll( 13 export function useTableScroll(
12 propsRef: ComputedRef<BasicTableProps>, 14 propsRef: ComputedRef<BasicTableProps>,
13 - tableElRef: Ref<ComponentRef> 15 + tableElRef: Ref<ComponentRef>,
  16 + columnsRef: ComputedRef<BasicColumn[]>,
  17 + rowSelectionRef: ComputedRef<TableRowSelection<any> | null>
14 ) { 18 ) {
15 const tableHeightRef: Ref<Nullable<number>> = ref(null); 19 const tableHeightRef: Ref<Nullable<number>> = ref(null);
16 20
17 const modalFn = useModalContext(); 21 const modalFn = useModalContext();
18 22
  23 + // const [debounceCalcTableHeight] = useDebounce(calcTableHeight, 80);
  24 + const [debounceRedoHeight] = useDebounce(redoHeight, 250);
  25 +
19 const getCanResize = computed(() => { 26 const getCanResize = computed(() => {
20 const { canResize, scroll } = unref(propsRef); 27 const { canResize, scroll } = unref(propsRef);
21 return canResize && !(scroll || {}).y; 28 return canResize && !(scroll || {}).y;
22 }); 29 });
23 30
24 watchEffect(() => { 31 watchEffect(() => {
25 - redoHeight(); 32 + unref(getCanResize) && debounceRedoHeight();
26 }); 33 });
27 34
28 function redoHeight() { 35 function redoHeight() {
@@ -33,6 +40,12 @@ export function useTableScroll( @@ -33,6 +40,12 @@ export function useTableScroll(
33 } 40 }
34 } 41 }
35 42
  43 + function setHeight(heigh: number) {
  44 + tableHeightRef.value = heigh;
  45 + // Solve the problem of modal adaptive height calculation when the form is placed in the modal
  46 + modalFn?.redoModalHeight?.();
  47 + }
  48 +
36 // No need to repeat queries 49 // No need to repeat queries
37 let paginationEl: HTMLElement | null; 50 let paginationEl: HTMLElement | null;
38 let footerEl: HTMLElement | null; 51 let footerEl: HTMLElement | null;
@@ -87,7 +100,7 @@ export function useTableScroll( @@ -87,7 +100,7 @@ export function useTableScroll(
87 headerHeight = (headEl as HTMLElement).offsetHeight; 100 headerHeight = (headEl as HTMLElement).offsetHeight;
88 } 101 }
89 102
90 - const height = 103 + let height =
91 bottomIncludeBody - 104 bottomIncludeBody -
92 (resizeHeightOffset || 0) - 105 (resizeHeightOffset || 0) -
93 paddingHeight - 106 paddingHeight -
@@ -96,21 +109,41 @@ export function useTableScroll( @@ -96,21 +109,41 @@ export function useTableScroll(
96 footerHeight - 109 footerHeight -
97 headerHeight; 110 headerHeight;
98 111
99 - setTimeout(() => {  
100 - tableHeightRef.value = (height > maxHeight! ? (maxHeight as number) : height) ?? height;  
101 - // Solve the problem of modal adaptive height calculation when the form is placed in the modal  
102 - modalFn?.redoModalHeight?.();  
103 - }, 0); 112 + height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
  113 + setHeight(height);
104 } 114 }
105 115
106 - useWindowSizeFn(calcTableHeight, 100); 116 + useWindowSizeFn(calcTableHeight, 200);
  117 +
  118 + const getScrollX = computed(() => {
  119 + let width = 0;
  120 + if (unref(rowSelectionRef)) {
  121 + width += 60;
  122 + }
  123 +
  124 + // TODO props
  125 + const NORMAL_WIDTH = 150;
  126 +
  127 + const columns = unref(columnsRef);
  128 +
  129 + columns.forEach((item) => {
  130 + width += Number.parseInt(item.width as string) || 0;
  131 + });
  132 + const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width'));
  133 +
  134 + const len = unsetWidthColumns.length;
  135 + if (len !== 0) {
  136 + width += len * NORMAL_WIDTH;
  137 + }
  138 + return width;
  139 + });
107 140
108 const getScrollRef = computed(() => { 141 const getScrollRef = computed(() => {
109 const tableHeight = unref(tableHeightRef); 142 const tableHeight = unref(tableHeightRef);
110 const { canResize, scroll } = unref(propsRef); 143 const { canResize, scroll } = unref(propsRef);
111 144
112 return { 145 return {
113 - x: '100%', 146 + x: unref(getScrollX),
114 y: canResize ? tableHeight : null, 147 y: canResize ? tableHeight : null,
115 scrollToFirstRowOnChange: false, 148 scrollToFirstRowOnChange: false,
116 ...scroll, 149 ...scroll,
src/components/Table/src/hooks/useTableStyle.ts
@@ -2,14 +2,14 @@ import type { ComputedRef } from &#39;vue&#39;; @@ -2,14 +2,14 @@ import type { ComputedRef } from &#39;vue&#39;;
2 import type { BasicTableProps, TableCustomRecord } from '../types/table'; 2 import type { BasicTableProps, TableCustomRecord } from '../types/table';
3 import { unref } from 'vue'; 3 import { unref } from 'vue';
4 import { isFunction } from '/@/utils/is'; 4 import { isFunction } from '/@/utils/is';
5 -export function useTableStyle(propsRef: ComputedRef<BasicTableProps>) { 5 +export function useTableStyle(propsRef: ComputedRef<BasicTableProps>, prefixCls: string) {
6 function getRowClassName(record: TableCustomRecord, index: number) { 6 function getRowClassName(record: TableCustomRecord, index: number) {
7 const { striped, rowClassName } = unref(propsRef); 7 const { striped, rowClassName } = unref(propsRef);
8 if (!striped) return; 8 if (!striped) return;
9 if (rowClassName && isFunction(rowClassName)) { 9 if (rowClassName && isFunction(rowClassName)) {
10 return rowClassName(record); 10 return rowClassName(record);
11 } 11 }
12 - return (index || 0) % 2 === 1 ? 'basic-table-row__striped' : ''; 12 + return (index || 0) % 2 === 1 ? `${prefixCls}-row__striped` : '';
13 } 13 }
14 14
15 return { 15 return {
src/components/Table/src/props.ts
@@ -75,7 +75,7 @@ export const basicProps = { @@ -75,7 +75,7 @@ export const basicProps = {
75 }, 75 },
76 columns: { 76 columns: {
77 type: [Array] as PropType<BasicColumn[]>, 77 type: [Array] as PropType<BasicColumn[]>,
78 - default: null, 78 + default: () => [],
79 }, 79 },
80 showIndexColumn: propTypes.bool.def(true), 80 showIndexColumn: propTypes.bool.def(true),
81 indexColumnProps: { 81 indexColumnProps: {
@@ -95,7 +95,7 @@ export const basicProps = { @@ -95,7 +95,7 @@ export const basicProps = {
95 default: null, 95 default: null,
96 }, 96 },
97 title: { 97 title: {
98 - type: [String, Function] as PropType<string | ((data: any) => any)>, 98 + type: [String, Function] as PropType<string | ((data: Recordable) => string)>,
99 default: null, 99 default: null,
100 }, 100 },
101 titleHelpMessage: { 101 titleHelpMessage: {
src/components/Table/src/style/editable-cell.less
1 -@import (reference) '../../../../design/index.less';  
2 -  
3 @prefix-cls: ~'editable-cell'; 1 @prefix-cls: ~'editable-cell';
4 2
5 .@{prefix-cls} { 3 .@{prefix-cls} {
src/components/Table/src/style/index.less
1 -@import (reference) '../../../../design/index.less';  
2 @border-color: #cecece4d; 1 @border-color: #cecece4d;
3 2
4 -.basic-table {  
5 - &-title {  
6 - display: flex;  
7 - justify-content: space-between;  
8 - align-items: center; 3 +@prefix-cls: ~'@{namespace}-basic-table';
  4 +
  5 +.@{prefix-cls} {
  6 + &-form-container {
  7 + padding: 16px;
  8 +
  9 + .ant-form {
  10 + padding: 20px 20px 4px 12px;
  11 + margin-bottom: 18px;
  12 + background: #fff;
  13 + border-radius: 4px;
  14 + }
  15 +
  16 + .ant-table-wrapper {
  17 + border-radius: 2px;
  18 + }
9 } 19 }
10 20
11 &-row__striped { 21 &-row__striped {
@@ -22,28 +32,16 @@ @@ -22,28 +32,16 @@
22 } 32 }
23 } 33 }
24 34
25 - &-action {  
26 - display: flex;  
27 -  
28 - button {  
29 - display: flex;  
30 - align-items: center;  
31 - }  
32 - }  
33 -  
34 - &-toolbar {  
35 - display: flex;  
36 - align-items: center;  
37 -  
38 - > * {  
39 - margin-right: 10px; 35 + &--inset {
  36 + .ant-table-wrapper {
  37 + padding: 0;
40 } 38 }
41 } 39 }
42 40
43 .ant-table-wrapper { 41 .ant-table-wrapper {
44 padding: 8px; 42 padding: 8px;
45 background: #fff; 43 background: #fff;
46 - border-radius: 2px; 44 + border-radius: 4px;
47 45
48 .ant-table-title { 46 .ant-table-title {
49 padding: 0 0 8px 0 !important; 47 padding: 0 0 8px 0 !important;
@@ -54,12 +52,6 @@ @@ -54,12 +52,6 @@
54 } 52 }
55 } 53 }
56 54
57 - &.inset {  
58 - .ant-table-wrapper {  
59 - padding: 0;  
60 - }  
61 - }  
62 -  
63 // 55 //
64 .ant-table { 56 .ant-table {
65 border: none; 57 border: none;
@@ -194,18 +186,3 @@ @@ -194,18 +186,3 @@
194 } 186 }
195 } 187 }
196 } 188 }
197 -  
198 -.table-form-container {  
199 - padding: 16px;  
200 -  
201 - .ant-form {  
202 - padding: 20px 20px 4px 12px;  
203 - margin-bottom: 18px;  
204 - background: #fff;  
205 - border-radius: 2px;  
206 - }  
207 -  
208 - .ant-table-wrapper {  
209 - border-radius: 2px;  
210 - }  
211 -}  
src/components/Table/src/types/table.ts
@@ -82,6 +82,7 @@ export interface FetchParams { @@ -82,6 +82,7 @@ export interface FetchParams {
82 export interface GetColumnsParams { 82 export interface GetColumnsParams {
83 ignoreIndex?: boolean; 83 ignoreIndex?: boolean;
84 ignoreAction?: boolean; 84 ignoreAction?: boolean;
  85 + sort?: boolean;
85 } 86 }
86 87
87 export type SizeType = 'default' | 'middle' | 'small' | 'large'; 88 export type SizeType = 'default' | 'middle' | 'small' | 'large';
@@ -93,16 +94,18 @@ export interface TableActionType { @@ -93,16 +94,18 @@ export interface TableActionType {
93 getSelectRowKeys: () => string[]; 94 getSelectRowKeys: () => string[];
94 deleteSelectRowByKey: (key: string) => void; 95 deleteSelectRowByKey: (key: string) => void;
95 setPagination: (info: Partial<PaginationProps>) => void; 96 setPagination: (info: Partial<PaginationProps>) => void;
96 - setTableData: <T = any>(values: T[]) => void; 97 + setTableData: <T = Recordable>(values: T[]) => void;
97 getColumns: (opt?: GetColumnsParams) => BasicColumn[]; 98 getColumns: (opt?: GetColumnsParams) => BasicColumn[];
98 setColumns: (columns: BasicColumn[] | string[]) => void; 99 setColumns: (columns: BasicColumn[] | string[]) => void;
99 - getDataSource: <T = any>() => T[]; 100 + getDataSource: <T = Recordable>() => T[];
100 setLoading: (loading: boolean) => void; 101 setLoading: (loading: boolean) => void;
101 setProps: (props: Partial<BasicTableProps>) => void; 102 setProps: (props: Partial<BasicTableProps>) => void;
102 redoHeight: () => void; 103 redoHeight: () => void;
103 setSelectedRowKeys: (rowKeys: string[] | number[]) => void; 104 setSelectedRowKeys: (rowKeys: string[] | number[]) => void;
104 getPaginationRef: () => PaginationProps | boolean; 105 getPaginationRef: () => PaginationProps | boolean;
105 getSize: () => SizeType; 106 getSize: () => SizeType;
  107 + getRowSelection: () => TableRowSelection<Recordable>;
  108 + getCacheColumns: () => BasicColumn[];
106 } 109 }
107 110
108 export interface FetchSetting { 111 export interface FetchSetting {
@@ -308,7 +311,7 @@ export interface BasicTableProps&lt;T = any&gt; { @@ -308,7 +311,7 @@ export interface BasicTableProps&lt;T = any&gt; {
308 * Table title renderer 311 * Table title renderer
309 * @type Function | ScopedSlot 312 * @type Function | ScopedSlot
310 */ 313 */
311 - title?: VNodeChild | JSX.Element; 314 + title?: VNodeChild | JSX.Element | string | ((data: Recordable) => string);
312 315
313 /** 316 /**
314 * Set props on per header row 317 * Set props on per header row
@@ -378,4 +381,6 @@ export interface BasicColumn extends ColumnProps { @@ -378,4 +381,6 @@ export interface BasicColumn extends ColumnProps {
378 flag?: 'INDEX' | 'DEFAULT' | 'CHECKBOX' | 'RADIO' | 'ACTION'; 381 flag?: 'INDEX' | 'DEFAULT' | 'CHECKBOX' | 'RADIO' | 'ACTION';
379 382
380 slots?: Indexable; 383 slots?: Indexable;
  384 +
  385 + defaultHidden?: boolean;
381 } 386 }
src/components/Table/src/types/tableAction.ts
@@ -5,6 +5,8 @@ export interface ActionItem extends ButtonProps { @@ -5,6 +5,8 @@ export interface ActionItem extends ButtonProps {
5 color?: 'success' | 'error' | 'warning'; 5 color?: 'success' | 'error' | 'warning';
6 icon?: string; 6 icon?: string;
7 popConfirm?: PopConfirm; 7 popConfirm?: PopConfirm;
  8 + disabled?: boolean;
  9 + divider?: boolean;
8 } 10 }
9 11
10 export interface PopConfirm { 12 export interface PopConfirm {
src/design/ant/index.less
@@ -18,6 +18,10 @@ @@ -18,6 +18,10 @@
18 } 18 }
19 } 19 }
20 20
  21 +.ant-image-preview-operations {
  22 + background: rgba(0, 0, 0, 0.3);
  23 +}
  24 +
21 // ================================= 25 // =================================
22 // ==============descriptions======= 26 // ==============descriptions=======
23 // ================================= 27 // =================================
src/design/config.less 0 → 100644
  1 +@import 'color.less';
  2 +@import 'var/index.less';
  3 +@import 'mixins.less';
src/design/index.less
1 -@import './transition/index.less'; 1 +@import 'transition/index.less';
2 @import 'var/index.less'; 2 @import 'var/index.less';
3 @import 'public.less'; 3 @import 'public.less';
4 @import 'mixins.less'; 4 @import 'mixins.less';
5 @import 'ant/index.less'; 5 @import 'ant/index.less';
6 -@import './global.less'; 6 +@import 'global.less';
7 7
8 *, 8 *,
9 *::before, 9 *::before,
src/design/var/index.less
@@ -34,3 +34,9 @@ @@ -34,3 +34,9 @@
34 34
35 // left-menu 35 // left-menu
36 @app-menu-item-height: 42px; 36 @app-menu-item-height: 42px;
  37 +
  38 +.bem(@n;@content) {
  39 + @{namespace}-@{n} {
  40 + @content();
  41 + }
  42 +}
src/hooks/component/useFormItem.ts
1 import type { UnwrapRef } from 'vue'; 1 import type { UnwrapRef } from 'vue';
2 -import { reactive, readonly, computed, getCurrentInstance } from 'vue'; 2 +import { reactive, readonly, computed, getCurrentInstance, watchEffect } from 'vue';
3 3
4 import { isEqual } from 'lodash-es'; 4 import { isEqual } from 'lodash-es';
5 5
@@ -20,6 +20,11 @@ export function useRuleFormItem&lt;T extends Indexable&gt;( @@ -20,6 +20,11 @@ export function useRuleFormItem&lt;T extends Indexable&gt;(
20 const setState = (val: UnwrapRef<T[keyof T]>) => { 20 const setState = (val: UnwrapRef<T[keyof T]>) => {
21 innerState.value = val as T[keyof T]; 21 innerState.value = val as T[keyof T];
22 }; 22 };
  23 +
  24 + watchEffect(() => {
  25 + innerState.value = props[key];
  26 + });
  27 +
23 const state = computed({ 28 const state = computed({
24 get() { 29 get() {
25 return innerState.value; 30 return innerState.value;
src/hooks/core/useContext.ts
@@ -25,7 +25,6 @@ export function createContext&lt;T&gt;( @@ -25,7 +25,6 @@ export function createContext&lt;T&gt;(
25 const { readonly = true, createProvider = false } = options; 25 const { readonly = true, createProvider = false } = options;
26 26
27 const state = reactive(context); 27 const state = reactive(context);
28 -  
29 const provideData = readonly ? defineReadonly(state) : state; 28 const provideData = readonly ? defineReadonly(state) : state;
30 !createProvider && provide(key, provideData); 29 !createProvider && provide(key, provideData);
31 30
src/hooks/web/useFullScreen.ts
@@ -17,7 +17,7 @@ type FSEPropName = @@ -17,7 +17,7 @@ type FSEPropName =
17 | 'fullscreenElement'; 17 | 'fullscreenElement';
18 18
19 export function useFullscreen( 19 export function useFullscreen(
20 - target: Ref<Nullable<HTMLElement>> = ref(document.documentElement), 20 + target: Ref<Nullable<HTMLElement>> | Nullable<HTMLElement> = ref(document.documentElement),
21 options?: FullscreenOptions 21 options?: FullscreenOptions
22 ) { 22 ) {
23 const isFullscreenRef = ref(false); 23 const isFullscreenRef = ref(false);
@@ -43,7 +43,7 @@ export function useFullscreen( @@ -43,7 +43,7 @@ export function useFullscreen(
43 } 43 }
44 function enterFullscreen(): Promise<void> { 44 function enterFullscreen(): Promise<void> {
45 isFullscreenRef.value = true; 45 isFullscreenRef.value = true;
46 - return (target.value as any)[RFC_METHOD_NAME](options); 46 + return (unref(target) as any)[RFC_METHOD_NAME](options);
47 } 47 }
48 48
49 function exitFullscreen(): Promise<void> { 49 function exitFullscreen(): Promise<void> {
@@ -55,7 +55,9 @@ export function useFullscreen( @@ -55,7 +55,9 @@ export function useFullscreen(
55 return unref(target) === (document as any)[FSE_PROP_NAME]; 55 return unref(target) === (document as any)[FSE_PROP_NAME];
56 } 56 }
57 57
58 - function toggleFullscreen(): Promise<void> { 58 + async function toggleFullscreen(): Promise<void> {
  59 + if (!unref(target)) return;
  60 +
59 if (isFullscreen()) { 61 if (isFullscreen()) {
60 return exitFullscreen(); 62 return exitFullscreen();
61 } else { 63 } else {
src/hooks/web/useSortable.ts 0 → 100644
  1 +import Sortable from 'sortablejs';
  2 +import { nextTick, unref } from 'vue';
  3 +import type { Ref } from 'vue';
  4 +
  5 +export function useSortable(el: HTMLElement | Ref<HTMLElement>, options?: Sortable.Options) {
  6 + function initSortable() {
  7 + nextTick(() => {
  8 + if (!el) return;
  9 + Sortable.create(unref(el), {
  10 + animation: 500,
  11 + delay: 400,
  12 + delayOnTouchOnly: true,
  13 + ...options,
  14 + });
  15 + });
  16 + }
  17 +
  18 + return { initSortable };
  19 +}
src/layouts/default/tabs/useMultipleTabs.ts
1 -import Sortable from 'sortablejs';  
2 -import { toRaw, ref, nextTick, onMounted } from 'vue'; 1 +import { toRaw, ref, nextTick } from 'vue';
3 import { RouteLocationNormalized } from 'vue-router'; 2 import { RouteLocationNormalized } from 'vue-router';
4 import { useProjectSetting } from '/@/hooks/setting'; 3 import { useProjectSetting } from '/@/hooks/setting';
5 import { useDesign } from '/@/hooks/web/useDesign'; 4 import { useDesign } from '/@/hooks/web/useDesign';
  5 +import { useSortable } from '/@/hooks/web/useSortable';
6 import router from '/@/router'; 6 import router from '/@/router';
7 import { tabStore } from '/@/store/modules/tab'; 7 import { tabStore } from '/@/store/modules/tab';
8 import { isNullAndUnDef } from '/@/utils/is'; 8 import { isNullAndUnDef } from '/@/utils/is';
@@ -50,36 +50,25 @@ export function useTabsDrag(affixTextList: string[]) { @@ -50,36 +50,25 @@ export function useTabsDrag(affixTextList: string[]) {
50 const { multiTabsSetting } = useProjectSetting(); 50 const { multiTabsSetting } = useProjectSetting();
51 51
52 const { prefixCls } = useDesign('multiple-tabs'); 52 const { prefixCls } = useDesign('multiple-tabs');
53 -  
54 - function initSortableTabs() { 53 + nextTick(() => {
55 if (!multiTabsSetting.canDrag) return; 54 if (!multiTabsSetting.canDrag) return;
56 - nextTick(() => {  
57 - const el = document.querySelectorAll(`.${prefixCls} .ant-tabs-nav > div`)?.[0] as HTMLElement;  
58 -  
59 - if (!el) return;  
60 - Sortable.create(el, {  
61 - animation: 500,  
62 - delay: 400,  
63 - delayOnTouchOnly: true,  
64 - filter: (e: ChangeEvent) => {  
65 - const text = e?.target?.innerText;  
66 - if (!text) return false;  
67 - return affixTextList.includes(text);  
68 - },  
69 - onEnd: (evt) => {  
70 - const { oldIndex, newIndex } = evt; 55 + const el = document.querySelectorAll(`.${prefixCls} .ant-tabs-nav > div`)?.[0] as HTMLElement;
  56 + const { initSortable } = useSortable(el, {
  57 + filter: (e: ChangeEvent) => {
  58 + const text = e?.target?.innerText;
  59 + if (!text) return false;
  60 + return affixTextList.includes(text);
  61 + },
  62 + onEnd: (evt) => {
  63 + const { oldIndex, newIndex } = evt;
71 64
72 - if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {  
73 - return;  
74 - } 65 + if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
  66 + return;
  67 + }
75 68
76 - tabStore.commitSortTabs({ oldIndex, newIndex });  
77 - },  
78 - }); 69 + tabStore.commitSortTabs({ oldIndex, newIndex });
  70 + },
79 }); 71 });
80 - }  
81 -  
82 - onMounted(() => {  
83 - initSortableTabs(); 72 + initSortable();
84 }); 73 });
85 } 74 }
src/locales/lang/en/component/app.ts
@@ -5,4 +5,7 @@ export default { @@ -5,4 +5,7 @@ export default {
5 toSearch: 'to search', 5 toSearch: 'to search',
6 toNavigate: 'to navigate', 6 toNavigate: 'to navigate',
7 toClose: 'to close', 7 toClose: 'to close',
  8 +
  9 + okText: 'Confirm',
  10 + cancelText: 'Cancel',
8 }; 11 };
src/locales/lang/en/component/table.ts
@@ -6,7 +6,11 @@ export default { @@ -6,7 +6,11 @@ export default {
6 settingDensSmall: 'Compact', 6 settingDensSmall: 'Compact',
7 settingColumn: 'Column settings', 7 settingColumn: 'Column settings',
8 settingColumnShow: 'Column display', 8 settingColumnShow: 'Column display',
  9 + settingIndexColumnShow: 'Index Column',
  10 + settingSelectColumnShow: 'Selection Column',
9 settingReset: 'Reset', 11 settingReset: 'Reset',
  12 + settingFixedLeft: 'Fixed Left',
  13 + settingFixedRight: 'Fixed Right',
10 settingFullScreen: 'Full Screen', 14 settingFullScreen: 'Full Screen',
11 15
12 index: 'Index', 16 index: 'Index',
src/locales/lang/zh_CN/component/app.ts
@@ -5,4 +5,6 @@ export default { @@ -5,4 +5,6 @@ export default {
5 toSearch: '确认', 5 toSearch: '确认',
6 toNavigate: '切换', 6 toNavigate: '切换',
7 toClose: '关闭', 7 toClose: '关闭',
  8 + okText: '确认',
  9 + cancelText: '取消',
8 }; 10 };
src/locales/lang/zh_CN/component/table.ts
@@ -7,6 +7,10 @@ export default { @@ -7,6 +7,10 @@ export default {
7 settingColumn: '列设置', 7 settingColumn: '列设置',
8 settingColumnShow: '列展示', 8 settingColumnShow: '列展示',
9 settingReset: '重置', 9 settingReset: '重置',
  10 + settingIndexColumnShow: '序号列',
  11 + settingSelectColumnShow: '勾选列',
  12 + settingFixedLeft: '固定到左侧',
  13 + settingFixedRight: '固定到右侧',
10 settingFullScreen: '全屏', 14 settingFullScreen: '全屏',
11 15
12 index: '序号', 16 index: '序号',
src/setup/App.ts
@@ -11,7 +11,6 @@ import { PROJ_CFG_KEY } from &#39;/@/enums/cacheEnum&#39;; @@ -11,7 +11,6 @@ import { PROJ_CFG_KEY } from &#39;/@/enums/cacheEnum&#39;;
11 11
12 import projectSetting from '/@/settings/projectSetting'; 12 import projectSetting from '/@/settings/projectSetting';
13 import { getLocal } from '/@/utils/helper/persistent'; 13 import { getLocal } from '/@/utils/helper/persistent';
14 -import { isUnDef, isNull } from '/@/utils/is';  
15 import { 14 import {
16 updateGrayMode, 15 updateGrayMode,
17 updateColorWeak, 16 updateColorWeak,
@@ -76,16 +75,3 @@ export function initAppConfigStore() { @@ -76,16 +75,3 @@ export function initAppConfigStore() {
76 } 75 }
77 appStore.commitProjectConfigState(projCfg); 76 appStore.commitProjectConfigState(projCfg);
78 } 77 }
79 -  
80 -// antdv Config Provider  
81 -export function getConfigProvider() {  
82 - function transformCellText({ text }: { text: string }) {  
83 - if (isNull(text) || isUnDef(text)) {  
84 - return ' - ';  
85 - }  
86 - return text;  
87 - }  
88 - return {  
89 - transformCellText,  
90 - };  
91 -}  
src/store/modules/tab.ts
@@ -182,7 +182,7 @@ class Tab extends VuexModule { @@ -182,7 +182,7 @@ class Tab extends VuexModule {
182 @Action 182 @Action
183 addTabAction(route: RouteLocationNormalized) { 183 addTabAction(route: RouteLocationNormalized) {
184 const { path, name } = route; 184 const { path, name } = route;
185 - // 404 页面不需要添加tab 185 + // 404 The page does not need to add a tab
186 if ( 186 if (
187 path === PageEnum.ERROR_PAGE || 187 path === PageEnum.ERROR_PAGE ||
188 !name || 188 !name ||
src/store/modules/user.ts
@@ -106,12 +106,13 @@ class User extends VuexModule { @@ -106,12 +106,13 @@ class User extends VuexModule {
106 const data = await loginApi(loginParams, mode); 106 const data = await loginApi(loginParams, mode);
107 107
108 const { token, userId } = data; 108 const { token, userId } = data;
109 - // get user info  
110 - const userInfo = await this.getUserInfoAction({ userId });  
111 109
112 // save token 110 // save token
113 this.commitTokenState(token); 111 this.commitTokenState(token);
114 112
  113 + // get user info
  114 + const userInfo = await this.getUserInfoAction({ userId });
  115 +
115 // const name = FULL_PAGE_NOT_FOUND_ROUTE.name; 116 // const name = FULL_PAGE_NOT_FOUND_ROUTE.name;
116 // name && router.removeRoute(name); 117 // name && router.removeRoute(name);
117 goHome && (await router.replace(PageEnum.BASE_HOME)); 118 goHome && (await router.replace(PageEnum.BASE_HOME));
src/utils/index.ts
@@ -8,10 +8,7 @@ export const now = () =&gt; Date.now(); @@ -8,10 +8,7 @@ export const now = () =&gt; Date.now();
8 * @description: Set ui mount node 8 * @description: Set ui mount node
9 */ 9 */
10 export function getPopupContainer(node?: HTMLElement): HTMLElement { 10 export function getPopupContainer(node?: HTMLElement): HTMLElement {
11 - if (node) {  
12 - return node.parentNode as HTMLElement;  
13 - }  
14 - return document.body; 11 + return (node?.parentNode as HTMLElement) ?? document.body;
15 } 12 }
16 13
17 /** 14 /**
src/views/demo/form/index.vue
@@ -224,6 +224,7 @@ @@ -224,6 +224,7 @@
224 colProps: { 224 colProps: {
225 span: 8, 225 span: 8,
226 }, 226 },
  227 + defaultValue: '0',
227 }, 228 },
228 { 229 {
229 field: 'field20', 230 field: 'field20',
src/views/demo/table/FormTable.vue
1 <template> 1 <template>
2 - <BasicTable @register="registerTable" /> 2 + <BasicTable @register="registerTable">
  3 + <template #form-custom> custom-slot</template>
  4 + </BasicTable>
3 </template> 5 </template>
4 <script lang="ts"> 6 <script lang="ts">
5 import { defineComponent } from 'vue'; 7 import { defineComponent } from 'vue';
@@ -18,6 +20,7 @@ @@ -18,6 +20,7 @@
18 useSearchForm: true, 20 useSearchForm: true,
19 formConfig: getFormConfig(), 21 formConfig: getFormConfig(),
20 showTableSetting: true, 22 showTableSetting: true,
  23 + rowSelection: { type: 'checkbox' },
21 }); 24 });
22 25
23 return { 26 return {
src/views/demo/table/tableData.tsx
@@ -6,7 +6,8 @@ export function getBasicColumns(): BasicColumn[] { @@ -6,7 +6,8 @@ export function getBasicColumns(): BasicColumn[] {
6 { 6 {
7 title: 'ID', 7 title: 'ID',
8 dataIndex: 'id', 8 dataIndex: 'id',
9 - width: 150, 9 + fixed: 'left',
  10 + width: 400,
10 }, 11 },
11 { 12 {
12 title: '姓名', 13 title: '姓名',
@@ -21,6 +22,7 @@ export function getBasicColumns(): BasicColumn[] { @@ -21,6 +22,7 @@ export function getBasicColumns(): BasicColumn[] {
21 title: '编号', 22 title: '编号',
22 dataIndex: 'no', 23 dataIndex: 'no',
23 width: 150, 24 width: 150,
  25 + defaultHidden: true,
24 }, 26 },
25 { 27 {
26 title: '开始时间', 28 title: '开始时间',
@@ -42,6 +44,8 @@ export function getBasicShortColumns(): BasicColumn[] { @@ -42,6 +44,8 @@ export function getBasicShortColumns(): BasicColumn[] {
42 title: 'ID', 44 title: 'ID',
43 width: 150, 45 width: 150,
44 dataIndex: 'id', 46 dataIndex: 'id',
  47 + sorter: true,
  48 + sortOrder: 'ascend',
45 }, 49 },
46 { 50 {
47 title: '姓名', 51 title: '姓名',
@@ -118,6 +122,7 @@ export function getCustomHeaderColumns(): BasicColumn[] { @@ -118,6 +122,7 @@ export function getCustomHeaderColumns(): BasicColumn[] {
118 { 122 {
119 // title: '地址', 123 // title: '地址',
120 dataIndex: 'address', 124 dataIndex: 'address',
  125 + width: 120,
121 slots: { title: 'customAddress' }, 126 slots: { title: 'customAddress' },
122 sorter: true, 127 sorter: true,
123 }, 128 },
@@ -236,6 +241,7 @@ export function getFormConfig(): Partial&lt;FormProps&gt; { @@ -236,6 +241,7 @@ export function getFormConfig(): Partial&lt;FormProps&gt; {
236 label: `字段33`, 241 label: `字段33`,
237 component: 'Select', 242 component: 'Select',
238 defaultValue: '1', 243 defaultValue: '1',
  244 + slot: 'custom',
239 componentProps: { 245 componentProps: {
240 options: [ 246 options: [
241 { 247 {
vite.config.ts
@@ -78,7 +78,11 @@ export default (mode: &#39;development&#39; | &#39;production&#39;): UserConfig =&gt; { @@ -78,7 +78,11 @@ export default (mode: &#39;development&#39; | &#39;production&#39;): UserConfig =&gt; {
78 78
79 cssPreprocessOptions: { 79 cssPreprocessOptions: {
80 less: { 80 less: {
81 - modifyVars: modifyVars, 81 + modifyVars: {
  82 + // reference : Avoid repeated references
  83 + hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
  84 + ...modifyVars,
  85 + },
82 javascriptEnabled: true, 86 javascriptEnabled: true,
83 }, 87 },
84 }, 88 },
yarn.lock
@@ -68,6 +68,15 @@ @@ -68,6 +68,15 @@
68 semver "^5.4.1" 68 semver "^5.4.1"
69 source-map "^0.5.0" 69 source-map "^0.5.0"
70 70
  71 +"@babel/generator@^7.12.1":
  72 + version "7.12.11"
  73 + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af"
  74 + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==
  75 + dependencies:
  76 + "@babel/types" "^7.12.11"
  77 + jsesc "^2.5.1"
  78 + source-map "^0.5.0"
  79 +
71 "@babel/generator@^7.12.10": 80 "@babel/generator@^7.12.10":
72 version "7.12.10" 81 version "7.12.10"
73 resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz#2b188fc329fb8e4f762181703beffc0fe6df3460" 82 resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz#2b188fc329fb8e4f762181703beffc0fe6df3460"
@@ -289,11 +298,21 @@ @@ -289,11 +298,21 @@
289 chalk "^2.0.0" 298 chalk "^2.0.0"
290 js-tokens "^4.0.0" 299 js-tokens "^4.0.0"
291 300
292 -"@babel/parser@^7.10.5", "@babel/parser@^7.11.0", "@babel/parser@^7.12.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.7": 301 +"@babel/parser@7.12.3":
  302 + version "7.12.3"
  303 + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd"
  304 + integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==
  305 +
  306 +"@babel/parser@^7.12.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.7":
293 version "7.12.10" 307 version "7.12.10"
294 resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz#824600d59e96aea26a5a2af5a9d812af05c3ae81" 308 resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz#824600d59e96aea26a5a2af5a9d812af05c3ae81"
295 integrity sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA== 309 integrity sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==
296 310
  311 +"@babel/parser@^7.12.1", "@babel/parser@^7.12.3":
  312 + version "7.12.11"
  313 + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79"
  314 + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==
  315 +
297 "@babel/plugin-proposal-async-generator-functions@^7.12.1": 316 "@babel/plugin-proposal-async-generator-functions@^7.12.1":
298 version "7.12.1" 317 version "7.12.1"
299 resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" 318 resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e"
@@ -833,7 +852,22 @@ @@ -833,7 +852,22 @@
833 "@babel/parser" "^7.12.7" 852 "@babel/parser" "^7.12.7"
834 "@babel/types" "^7.12.7" 853 "@babel/types" "^7.12.7"
835 854
836 -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": 855 +"@babel/traverse@7.12.1":
  856 + version "7.12.1"
  857 + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e"
  858 + integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==
  859 + dependencies:
  860 + "@babel/code-frame" "^7.10.4"
  861 + "@babel/generator" "^7.12.1"
  862 + "@babel/helper-function-name" "^7.10.4"
  863 + "@babel/helper-split-export-declaration" "^7.11.0"
  864 + "@babel/parser" "^7.12.1"
  865 + "@babel/types" "^7.12.1"
  866 + debug "^4.1.0"
  867 + globals "^11.1.0"
  868 + lodash "^4.17.19"
  869 +
  870 +"@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5":
837 version "7.12.10" 871 version "7.12.10"
838 resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a" 872 resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a"
839 integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg== 873 integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==
@@ -848,6 +882,15 @@ @@ -848,6 +882,15 @@
848 globals "^11.1.0" 882 globals "^11.1.0"
849 lodash "^4.17.19" 883 lodash "^4.17.19"
850 884
  885 +"@babel/types@7.12.1":
  886 + version "7.12.1"
  887 + resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae"
  888 + integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==
  889 + dependencies:
  890 + "@babel/helper-validator-identifier" "^7.10.4"
  891 + lodash "^4.17.19"
  892 + to-fast-properties "^2.0.0"
  893 +
851 "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": 894 "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4":
852 version "7.12.10" 895 version "7.12.10"
853 resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz#7965e4a7260b26f09c56bcfcb0498af1f6d9b260" 896 resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz#7965e4a7260b26f09c56bcfcb0498af1f6d9b260"
@@ -1091,6 +1134,23 @@ @@ -1091,6 +1134,23 @@
1091 "@intlify/runtime" "9.0.0-beta.14" 1134 "@intlify/runtime" "9.0.0-beta.14"
1092 "@intlify/shared" "9.0.0-beta.14" 1135 "@intlify/shared" "9.0.0-beta.14"
1093 1136
  1137 +"@intlify/core-base@9.0.0-beta.16":
  1138 + version "9.0.0-beta.16"
  1139 + resolved "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.0.0-beta.16.tgz#ab35802b982f52db20d4758d020c2dcd1724e7f9"
  1140 + integrity sha512-PJLDVYy3x8Mf9+XtWljEfk4Lo6mudopYlRvB89NQR3TkR+Tqkbcsegj09XdXpTKBYiq+yQrlZKZ0KEHb7l5Zuw==
  1141 + dependencies:
  1142 + "@intlify/message-compiler" "9.0.0-beta.16"
  1143 + "@intlify/message-resolver" "9.0.0-beta.16"
  1144 + "@intlify/runtime" "9.0.0-beta.16"
  1145 + "@intlify/shared" "9.0.0-beta.16"
  1146 +
  1147 +"@intlify/core@^9.0.0-beta.15":
  1148 + version "9.0.0-beta.16"
  1149 + resolved "https://registry.npmjs.org/@intlify/core/-/core-9.0.0-beta.16.tgz#d74d4678868b37b641bdf999552b237d84dacb88"
  1150 + integrity sha512-tPXf9rr+ZzG1zXgdLo8rCO2jws6eIXzJSaTvgnanZpfyyMKE+T8Ra5vVu3f/Sm0J7flT+z/Q3kLfnbpOMQ1UiQ==
  1151 + dependencies:
  1152 + "@intlify/core-base" "9.0.0-beta.16"
  1153 +
1094 "@intlify/message-compiler@9.0.0-beta.14": 1154 "@intlify/message-compiler@9.0.0-beta.14":
1095 version "9.0.0-beta.14" 1155 version "9.0.0-beta.14"
1096 resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.0.0-beta.14.tgz#4b5a4467459c402e71652075e9d95e5d85e85588" 1156 resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.0.0-beta.14.tgz#4b5a4467459c402e71652075e9d95e5d85e85588"
@@ -1100,11 +1160,25 @@ @@ -1100,11 +1160,25 @@
1100 "@intlify/shared" "9.0.0-beta.14" 1160 "@intlify/shared" "9.0.0-beta.14"
1101 source-map "0.6.1" 1161 source-map "0.6.1"
1102 1162
  1163 +"@intlify/message-compiler@9.0.0-beta.16":
  1164 + version "9.0.0-beta.16"
  1165 + resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.0.0-beta.16.tgz#359993251a303f148b3a325eca055cdbaf0cd95f"
  1166 + integrity sha512-dE4UZsbVl5TKogYdfrJ6nQKdin1R4XMKVBVa9dE1A8HVvVHBSLy6iQiYpcw8TwcEHIa+rFjuuHuh+IdN3eCw+g==
  1167 + dependencies:
  1168 + "@intlify/message-resolver" "9.0.0-beta.16"
  1169 + "@intlify/shared" "9.0.0-beta.16"
  1170 + source-map "0.6.1"
  1171 +
1103 "@intlify/message-resolver@9.0.0-beta.14": 1172 "@intlify/message-resolver@9.0.0-beta.14":
1104 version "9.0.0-beta.14" 1173 version "9.0.0-beta.14"
1105 resolved "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.0.0-beta.14.tgz#f964706650d71ef06669c17c29cb60500ef2617a" 1174 resolved "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.0.0-beta.14.tgz#f964706650d71ef06669c17c29cb60500ef2617a"
1106 integrity sha512-/PPLMHX0w/ECkG+Fmne8L3WVVVwAp3tpdisf5G775b49Fspy4dKXqkLXM2NZKhdguJbXWHXXXiRkr+mlhq8G9Q== 1175 integrity sha512-/PPLMHX0w/ECkG+Fmne8L3WVVVwAp3tpdisf5G775b49Fspy4dKXqkLXM2NZKhdguJbXWHXXXiRkr+mlhq8G9Q==
1107 1176
  1177 +"@intlify/message-resolver@9.0.0-beta.16":
  1178 + version "9.0.0-beta.16"
  1179 + resolved "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.0.0-beta.16.tgz#f8960344201050d17560f8d01f63e3cd0b9bf59c"
  1180 + integrity sha512-xwjsFuDDYEv7g1KE5QZRbrPgfsrNsDhYLtNYR7Tn4inzbmB6ipak2UlDzDcQGLieSFbe1WwAoNL0IXy4sUKboQ==
  1181 +
1108 "@intlify/runtime@9.0.0-beta.14": 1182 "@intlify/runtime@9.0.0-beta.14":
1109 version "9.0.0-beta.14" 1183 version "9.0.0-beta.14"
1110 resolved "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.0.0-beta.14.tgz#367f6b09c991c71905b73224e238aa8382976b2d" 1184 resolved "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.0.0-beta.14.tgz#367f6b09c991c71905b73224e238aa8382976b2d"
@@ -1114,11 +1188,25 @@ @@ -1114,11 +1188,25 @@
1114 "@intlify/message-resolver" "9.0.0-beta.14" 1188 "@intlify/message-resolver" "9.0.0-beta.14"
1115 "@intlify/shared" "9.0.0-beta.14" 1189 "@intlify/shared" "9.0.0-beta.14"
1116 1190
  1191 +"@intlify/runtime@9.0.0-beta.16":
  1192 + version "9.0.0-beta.16"
  1193 + resolved "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.0.0-beta.16.tgz#6a210a5b0984f9e295025e3dde5262108e0e69d9"
  1194 + integrity sha512-py+stHrbkBoEB2OsBB+rySevR+54uhybF54LToGjErr740R/AVuOVTJEKRS/LF9VvinGZZTu/WVOXcPpMfqt8Q==
  1195 + dependencies:
  1196 + "@intlify/message-compiler" "9.0.0-beta.16"
  1197 + "@intlify/message-resolver" "9.0.0-beta.16"
  1198 + "@intlify/shared" "9.0.0-beta.16"
  1199 +
1117 "@intlify/shared@9.0.0-beta.14": 1200 "@intlify/shared@9.0.0-beta.14":
1118 version "9.0.0-beta.14" 1201 version "9.0.0-beta.14"
1119 resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.0.0-beta.14.tgz#c221a45f666a40935f998d2e3c14451a516b9f56" 1202 resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.0.0-beta.14.tgz#c221a45f666a40935f998d2e3c14451a516b9f56"
1120 integrity sha512-f+Gev5GnrNLyieJCB6sB/qqe03XaMf6yJiAXG3IamZ4mp45oj2Lw9Oj3hAepDW36VUZK2wCIDmWy53pxJNIFpQ== 1203 integrity sha512-f+Gev5GnrNLyieJCB6sB/qqe03XaMf6yJiAXG3IamZ4mp45oj2Lw9Oj3hAepDW36VUZK2wCIDmWy53pxJNIFpQ==
1121 1204
  1205 +"@intlify/shared@9.0.0-beta.16":
  1206 + version "9.0.0-beta.16"
  1207 + resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.0.0-beta.16.tgz#51a80ca4705c93cb14c8f06398dfc550df09d67d"
  1208 + integrity sha512-A7GSOovcZn/NMoAmDc8FG9uRcFv6iygriK8+C6HFeOnMQ9X+T9f5A9bPtXhCOCiRpQm9SUtGqXedxO5Y8rz9/A==
  1209 +
1122 "@koa/cors@^3.1.0": 1210 "@koa/cors@^3.1.0":
1123 version "3.1.0" 1211 version "3.1.0"
1124 resolved "https://registry.npmjs.org/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2" 1212 resolved "https://registry.npmjs.org/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2"
@@ -1342,6 +1430,11 @@ @@ -1342,6 +1430,11 @@
1342 "@types/connect" "*" 1430 "@types/connect" "*"
1343 "@types/node" "*" 1431 "@types/node" "*"
1344 1432
  1433 +"@types/braces@*":
  1434 + version "3.0.0"
  1435 + resolved "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb"
  1436 + integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
  1437 +
1345 "@types/connect@*": 1438 "@types/connect@*":
1346 version "3.4.34" 1439 version "3.4.34"
1347 resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" 1440 resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
@@ -1499,6 +1592,13 @@ @@ -1499,6 +1592,13 @@
1499 dependencies: 1592 dependencies:
1500 "@types/unist" "*" 1593 "@types/unist" "*"
1501 1594
  1595 +"@types/micromatch@^4.0.1":
  1596 + version "4.0.1"
  1597 + resolved "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7"
  1598 + integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw==
  1599 + dependencies:
  1600 + "@types/braces" "*"
  1601 +
1502 "@types/mime@*": 1602 "@types/mime@*":
1503 version "2.0.3" 1603 version "2.0.3"
1504 resolved "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" 1604 resolved "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a"
@@ -1606,61 +1706,61 @@ @@ -1606,61 +1706,61 @@
1606 resolved "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.0.tgz#fbc1d941cc6d9d37d18405c513ba6b294f89b609" 1706 resolved "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.0.tgz#fbc1d941cc6d9d37d18405c513ba6b294f89b609"
1607 integrity sha512-GQLOT+SN20a+AI51y3fAimhyTF4Y0RG+YP3gf91OibIZ7CJmPFgoZi+ZR5a+vRbS01LbQosITWum4ATmJ1Z6Pg== 1707 integrity sha512-GQLOT+SN20a+AI51y3fAimhyTF4Y0RG+YP3gf91OibIZ7CJmPFgoZi+ZR5a+vRbS01LbQosITWum4ATmJ1Z6Pg==
1608 1708
1609 -"@typescript-eslint/eslint-plugin@^4.11.0":  
1610 - version "4.11.0"  
1611 - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.0.tgz#bc6c1e4175c0cf42083da4314f7931ad12f731cc"  
1612 - integrity sha512-x4arJMXBxyD6aBXLm3W7mSDZRiABzy+2PCLJbL7OPqlp53VXhaA1HKK7R2rTee5OlRhnUgnp8lZyVIqjnyPT6g== 1709 +"@typescript-eslint/eslint-plugin@^4.11.1":
  1710 + version "4.11.1"
  1711 + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.1.tgz#7579c6d17ad862154c10bc14b40e5427b729e209"
  1712 + integrity sha512-fABclAX2QIEDmTMk6Yd7Muv1CzFLwWM4505nETzRHpP3br6jfahD9UUJkhnJ/g2m7lwfz8IlswcwGGPGiq9exw==
1613 dependencies: 1713 dependencies:
1614 - "@typescript-eslint/experimental-utils" "4.11.0"  
1615 - "@typescript-eslint/scope-manager" "4.11.0" 1714 + "@typescript-eslint/experimental-utils" "4.11.1"
  1715 + "@typescript-eslint/scope-manager" "4.11.1"
1616 debug "^4.1.1" 1716 debug "^4.1.1"
1617 functional-red-black-tree "^1.0.1" 1717 functional-red-black-tree "^1.0.1"
1618 regexpp "^3.0.0" 1718 regexpp "^3.0.0"
1619 semver "^7.3.2" 1719 semver "^7.3.2"
1620 tsutils "^3.17.1" 1720 tsutils "^3.17.1"
1621 1721
1622 -"@typescript-eslint/experimental-utils@4.11.0":  
1623 - version "4.11.0"  
1624 - resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.0.tgz#d1a47cc6cfe1c080ce4ead79267574b9881a1565"  
1625 - integrity sha512-1VC6mSbYwl1FguKt8OgPs8xxaJgtqFpjY/UzUYDBKq4pfQ5lBvN2WVeqYkzf7evW42axUHYl2jm9tNyFsb8oLg== 1722 +"@typescript-eslint/experimental-utils@4.11.1":
  1723 + version "4.11.1"
  1724 + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.1.tgz#2dad3535b878c25c7424e40bfa79d899f3f485bc"
  1725 + integrity sha512-mAlWowT4A6h0TC9F+J5pdbEhjNiEMO+kqPKQ4sc3fVieKL71dEqfkKgtcFVSX3cjSBwYwhImaQ/mXQF0oaI38g==
1626 dependencies: 1726 dependencies:
1627 "@types/json-schema" "^7.0.3" 1727 "@types/json-schema" "^7.0.3"
1628 - "@typescript-eslint/scope-manager" "4.11.0"  
1629 - "@typescript-eslint/types" "4.11.0"  
1630 - "@typescript-eslint/typescript-estree" "4.11.0" 1728 + "@typescript-eslint/scope-manager" "4.11.1"
  1729 + "@typescript-eslint/types" "4.11.1"
  1730 + "@typescript-eslint/typescript-estree" "4.11.1"
1631 eslint-scope "^5.0.0" 1731 eslint-scope "^5.0.0"
1632 eslint-utils "^2.0.0" 1732 eslint-utils "^2.0.0"
1633 1733
1634 -"@typescript-eslint/parser@^4.11.0":  
1635 - version "4.11.0"  
1636 - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.11.0.tgz#1dd3d7e42708c10ce9f3aa64c63c0ab99868b4e2"  
1637 - integrity sha512-NBTtKCC7ZtuxEV5CrHUO4Pg2s784pvavc3cnz6V+oJvVbK4tH9135f/RBP6eUA2KHiFKAollSrgSctQGmHbqJQ== 1734 +"@typescript-eslint/parser@^4.11.1":
  1735 + version "4.11.1"
  1736 + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.11.1.tgz#981e18de2e019d6ca312596615f92e8f6f6598ed"
  1737 + integrity sha512-BJ3jwPQu1jeynJ5BrjLuGfK/UJu6uwHxJ/di7sanqmUmxzmyIcd3vz58PMR7wpi8k3iWq2Q11KMYgZbUpRoIPw==
1638 dependencies: 1738 dependencies:
1639 - "@typescript-eslint/scope-manager" "4.11.0"  
1640 - "@typescript-eslint/types" "4.11.0"  
1641 - "@typescript-eslint/typescript-estree" "4.11.0" 1739 + "@typescript-eslint/scope-manager" "4.11.1"
  1740 + "@typescript-eslint/types" "4.11.1"
  1741 + "@typescript-eslint/typescript-estree" "4.11.1"
1642 debug "^4.1.1" 1742 debug "^4.1.1"
1643 1743
1644 -"@typescript-eslint/scope-manager@4.11.0":  
1645 - version "4.11.0"  
1646 - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.0.tgz#2d906537db8a3a946721699e4fc0833810490254"  
1647 - integrity sha512-6VSTm/4vC2dHM3ySDW9Kl48en+yLNfVV6LECU8jodBHQOhO8adAVizaZ1fV0QGZnLQjQ/y0aBj5/KXPp2hBTjA== 1744 +"@typescript-eslint/scope-manager@4.11.1":
  1745 + version "4.11.1"
  1746 + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.1.tgz#72dc2b60b0029ab0888479b12bf83034920b4b69"
  1747 + integrity sha512-Al2P394dx+kXCl61fhrrZ1FTI7qsRDIUiVSuN6rTwss6lUn8uVO2+nnF4AvO0ug8vMsy3ShkbxLu/uWZdTtJMQ==
1648 dependencies: 1748 dependencies:
1649 - "@typescript-eslint/types" "4.11.0"  
1650 - "@typescript-eslint/visitor-keys" "4.11.0" 1749 + "@typescript-eslint/types" "4.11.1"
  1750 + "@typescript-eslint/visitor-keys" "4.11.1"
1651 1751
1652 -"@typescript-eslint/types@4.11.0":  
1653 - version "4.11.0"  
1654 - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.0.tgz#86cf95e7eac4ccfd183f9fcf1480cece7caf4ca4"  
1655 - integrity sha512-XXOdt/NPX++txOQHM1kUMgJUS43KSlXGdR/aDyEwuAEETwuPt02Nc7v+s57PzuSqMbNLclblQdv3YcWOdXhQ7g== 1752 +"@typescript-eslint/types@4.11.1":
  1753 + version "4.11.1"
  1754 + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.1.tgz#3ba30c965963ef9f8ced5a29938dd0c465bd3e05"
  1755 + integrity sha512-5kvd38wZpqGY4yP/6W3qhYX6Hz0NwUbijVsX2rxczpY6OXaMxh0+5E5uLJKVFwaBM7PJe1wnMym85NfKYIh6CA==
1656 1756
1657 -"@typescript-eslint/typescript-estree@4.11.0":  
1658 - version "4.11.0"  
1659 - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.0.tgz#1144d145841e5987d61c4c845442a24b24165a4b"  
1660 - integrity sha512-eA6sT5dE5RHAFhtcC+b5WDlUIGwnO9b0yrfGa1mIOIAjqwSQCpXbLiFmKTdRbQN/xH2EZkGqqLDrKUuYOZ0+Hg== 1757 +"@typescript-eslint/typescript-estree@4.11.1":
  1758 + version "4.11.1"
  1759 + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.1.tgz#a4416b4a65872a48773b9e47afabdf7519eb10bc"
  1760 + integrity sha512-tC7MKZIMRTYxQhrVAFoJq/DlRwv1bnqA4/S2r3+HuHibqvbrPcyf858lNzU7bFmy4mLeIHFYr34ar/1KumwyRw==
1661 dependencies: 1761 dependencies:
1662 - "@typescript-eslint/types" "4.11.0"  
1663 - "@typescript-eslint/visitor-keys" "4.11.0" 1762 + "@typescript-eslint/types" "4.11.1"
  1763 + "@typescript-eslint/visitor-keys" "4.11.1"
1664 debug "^4.1.1" 1764 debug "^4.1.1"
1665 globby "^11.0.1" 1765 globby "^11.0.1"
1666 is-glob "^4.0.1" 1766 is-glob "^4.0.1"
@@ -1668,15 +1768,15 @@ @@ -1668,15 +1768,15 @@
1668 semver "^7.3.2" 1768 semver "^7.3.2"
1669 tsutils "^3.17.1" 1769 tsutils "^3.17.1"
1670 1770
1671 -"@typescript-eslint/visitor-keys@4.11.0":  
1672 - version "4.11.0"  
1673 - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.0.tgz#906669a50f06aa744378bb84c7d5c4fdbc5b7d51"  
1674 - integrity sha512-tRYKyY0i7cMk6v4UIOCjl1LhuepC/pc6adQqJk4Is3YcC6k46HvsV9Wl7vQoLbm9qADgeujiT7KdLrylvFIQ+A== 1771 +"@typescript-eslint/visitor-keys@4.11.1":
  1772 + version "4.11.1"
  1773 + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.1.tgz#4c050a4c1f7239786e2dd4e69691436143024e05"
  1774 + integrity sha512-IrlBhD9bm4bdYcS8xpWarazkKXlE7iYb1HzRuyBP114mIaj5DJPo11Us1HgH60dTt41TCZXMaTCAW+OILIYPOg==
1675 dependencies: 1775 dependencies:
1676 - "@typescript-eslint/types" "4.11.0" 1776 + "@typescript-eslint/types" "4.11.1"
1677 eslint-visitor-keys "^2.0.0" 1777 eslint-visitor-keys "^2.0.0"
1678 1778
1679 -"@vue/compiler-core@*", "@vue/compiler-core@3.0.4", "@vue/compiler-core@^3.0.0-rc.5": 1779 +"@vue/compiler-core@3.0.4", "@vue/compiler-core@^3.0.0", "@vue/compiler-core@^3.0.1", "@vue/compiler-core@^3.0.2":
1680 version "3.0.4" 1780 version "3.0.4"
1681 resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.4.tgz#0122aca6eada4cb28b39ed930af917444755e330" 1781 resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.4.tgz#0122aca6eada4cb28b39ed930af917444755e330"
1682 integrity sha512-snpMICsbWTZqBFnPB03qr4DtiSxVYfDF3DvbDSkN9Z9NTM8Chl8E/lYhKBSsvauq91DAWAh8PU3lr9vrLyQsug== 1782 integrity sha512-snpMICsbWTZqBFnPB03qr4DtiSxVYfDF3DvbDSkN9Z9NTM8Chl8E/lYhKBSsvauq91DAWAh8PU3lr9vrLyQsug==
@@ -1695,7 +1795,7 @@ @@ -1695,7 +1795,7 @@
1695 "@vue/compiler-core" "3.0.4" 1795 "@vue/compiler-core" "3.0.4"
1696 "@vue/shared" "3.0.4" 1796 "@vue/shared" "3.0.4"
1697 1797
1698 -"@vue/compiler-sfc@*", "@vue/compiler-sfc@^3.0.0-rc.5", "@vue/compiler-sfc@^3.0.3", "@vue/compiler-sfc@^3.0.4": 1798 +"@vue/compiler-sfc@^3.0.3", "@vue/compiler-sfc@^3.0.4":
1699 version "3.0.4" 1799 version "3.0.4"
1700 resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.4.tgz#2119fe1e68d2c268aafa20461c82c139a9adf8e0" 1800 resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.4.tgz#2119fe1e68d2c268aafa20461c82c139a9adf8e0"
1701 integrity sha512-brDn6HTuK6R3oBCjtMPPsIpyJEZFinlnxjtBXww/goFJOJBAU9CrsdegwyZItNnixCFUIg4CLv4Nj1Eg/eKlfg== 1801 integrity sha512-brDn6HTuK6R3oBCjtMPPsIpyJEZFinlnxjtBXww/goFJOJBAU9CrsdegwyZItNnixCFUIg4CLv4Nj1Eg/eKlfg==
@@ -1759,75 +1859,97 @@ @@ -1759,75 +1859,97 @@
1759 resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.4.tgz#6dc50f593bdfdeaa6183d1dbc15e2d45e7c6b8b3" 1859 resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.4.tgz#6dc50f593bdfdeaa6183d1dbc15e2d45e7c6b8b3"
1760 integrity sha512-Swfbz31AaMX48CpFl+YmIrqOH9MgJMTrltG9e26A4ZxYx9LjGuMV+41WnxFzS3Bc9nbrc6sDPM37G6nIT8NJSg== 1860 integrity sha512-Swfbz31AaMX48CpFl+YmIrqOH9MgJMTrltG9e26A4ZxYx9LjGuMV+41WnxFzS3Bc9nbrc6sDPM37G6nIT8NJSg==
1761 1861
1762 -"@vuedx/analyze@0.2.4-0":  
1763 - version "0.2.4-0"  
1764 - resolved "https://registry.npmjs.org/@vuedx/analyze/-/analyze-0.2.4-0.tgz#52766a6dcd2867320409fe517540fd0bf0394d48"  
1765 - integrity sha512-GX5lqZPwyHLrJaL36L5qcBLBGcvTz/LiGwv1nwxuZ2HpO4rr2mH6CemA0mOKXiQ5aaqbAYqeAzMQf+i/AEViQg== 1862 +"@vuedx/analyze@0.4.0":
  1863 + version "0.4.0"
  1864 + resolved "https://registry.npmjs.org/@vuedx/analyze/-/analyze-0.4.0.tgz#a5ae608e8fedd0d9125e4ddb88b75a4a8165c991"
  1865 + integrity sha512-JHr5xjbzHNlAXY6pQER2SXzpnpDPINpfg9H1+eQo7e3dMwMdXj0f1nnJ9l3b3QCVR11jyr+xsWrqfuvNo2RJXg==
1766 dependencies: 1866 dependencies:
1767 "@babel/code-frame" "^7.10.4" 1867 "@babel/code-frame" "^7.10.4"
1768 - "@babel/parser" "^7.10.5"  
1769 - "@babel/traverse" "^7.11.0"  
1770 - "@babel/types" "^7.10.5"  
1771 - "@vue/compiler-core" "^3.0.0-rc.5"  
1772 - "@vue/compiler-sfc" "^3.0.0-rc.5" 1868 + "@babel/generator" "^7.12.1"
  1869 + "@babel/parser" "^7.12.3"
  1870 + "@babel/template" "^7.12.7"
  1871 + "@babel/traverse" "7.12.1"
  1872 + "@babel/types" "7.12.1"
  1873 + "@types/micromatch" "^4.0.1"
  1874 + "@vuedx/compiler-sfc" "0.4.0"
  1875 + "@vuedx/compiler-tsx" "0.4.0"
  1876 + "@vuedx/projectconfig" "0.4.0"
  1877 + "@vuedx/template-ast-types" "0.4.0"
1773 cli-highlight "^2.1.4" 1878 cli-highlight "^2.1.4"
1774 - commander "^6.0.0" 1879 + commander "^6.1.0"
1775 fast-glob "^3.2.4" 1880 fast-glob "^3.2.4"
1776 hash-sum "^2.0.0" 1881 hash-sum "^2.0.0"
  1882 + micromatch "^4.0.2"
1777 1883
1778 -"@vuedx/compiler-tsx@0.2.4-0":  
1779 - version "0.2.4-0"  
1780 - resolved "https://registry.npmjs.org/@vuedx/compiler-tsx/-/compiler-tsx-0.2.4-0.tgz#a4d734519f689e82287d5bbd8048cdcf1932aee6"  
1781 - integrity sha512-XzJdijqmHPiNNV555TgBfv/7iMmwmpQYCimpTtccrVch7m1R+64YZqtgg43lkWZLwwANhPVborJh/Pw8wCUokQ== 1884 +"@vuedx/compiler-sfc@0.4.0":
  1885 + version "0.4.0"
  1886 + resolved "https://registry.npmjs.org/@vuedx/compiler-sfc/-/compiler-sfc-0.4.0.tgz#2c3c85fdcd45b4f0e759179ea87d23c09a188c6d"
  1887 + integrity sha512-AXBi6V2wofbLUff8q2KAAOkfTgWnHcpB9Yqd3KpLhXsKXwGnt4Gt0NW2sjHTantnbAQWB4qxZohbNikHscNXuQ==
1782 dependencies: 1888 dependencies:
1783 - "@babel/parser" "^7.11.0"  
1784 - "@babel/types" "^7.11.0"  
1785 - "@vue/compiler-core" "^3.0.0-rc.5"  
1786 - "@vuedx/template-ast-types" "0.2.4-0"  
1787 - lodash.camelcase "^4.3.0" 1889 + "@vue/compiler-core" "^3.0.2"
  1890 + lru-cache "^6.0.0"
  1891 + source-map "^0.6.1"
1788 1892
1789 -"@vuedx/template-ast-types@0.2.4-0":  
1790 - version "0.2.4-0"  
1791 - resolved "https://registry.npmjs.org/@vuedx/template-ast-types/-/template-ast-types-0.2.4-0.tgz#a1cead2e9631f8fa710a9c5622412f600e290a1f"  
1792 - integrity sha512-9xFfTPH4rTxNsITOJMinlzDJf3+8VS/ao02gfHZMs57XgHszghYzVFKpfs2G0056xYAKrfoJSEJw51eGSB9KQA== 1893 +"@vuedx/compiler-tsx@0.4.0":
  1894 + version "0.4.0"
  1895 + resolved "https://registry.npmjs.org/@vuedx/compiler-tsx/-/compiler-tsx-0.4.0.tgz#f35c1ebbe4bb006cca12509882f6941d4c06408e"
  1896 + integrity sha512-L3zS8RXBVDdITCGih7wGbOURtgGyE5YN/HgKkmSsWLW/KrrUWldOdn9pe/31yixLRdqgpG+9TePauMw7n6HoNw==
1793 dependencies: 1897 dependencies:
1794 - "@vue/compiler-core" "^3.0.0-rc.5" 1898 + "@babel/parser" "7.12.3"
  1899 + "@babel/types" "7.12.1"
  1900 + "@vue/compiler-core" "^3.0.1"
  1901 + "@vuedx/template-ast-types" "0.4.0"
1795 1902
1796 -"@vuedx/typecheck@^0.2.4-0":  
1797 - version "0.2.4-0"  
1798 - resolved "https://registry.npmjs.org/@vuedx/typecheck/-/typecheck-0.2.4-0.tgz#d88e942b9b62d31cc8df3ffcfc16265b6da37665"  
1799 - integrity sha512-pOOgz5epvks6lcSfqCotm7fcen4UHl/h1pUiabtV/EKoNKh3OXMB8IBzRHwWv0h1SrkMuKVqMzj52liZIVZRfw== 1903 +"@vuedx/projectconfig@0.4.0":
  1904 + version "0.4.0"
  1905 + resolved "https://registry.npmjs.org/@vuedx/projectconfig/-/projectconfig-0.4.0.tgz#a3c39f24e18fef99260480c50214f9266b06ea52"
  1906 + integrity sha512-bBWEpG5pQHJuTYUEau0dvYdwakoGyphheq268FN8/EppzpbSOSligVDtS84AYCC8IKqyPf8I7f1Mma6kDyuBnQ==
  1907 +
  1908 +"@vuedx/template-ast-types@0.4.0":
  1909 + version "0.4.0"
  1910 + resolved "https://registry.npmjs.org/@vuedx/template-ast-types/-/template-ast-types-0.4.0.tgz#9a9ce25846273f8b578e00db6d50c5fdc1d3b33c"
  1911 + integrity sha512-WCUEJwEzYL7WSeA8zNXVlYtVK5aN8gbMAAt2/HZRGXKTcI3awawFrQv1c6wkAsQP4czvcdpz//y2Gmuh43KfNA==
  1912 + dependencies:
  1913 + "@vue/compiler-core" "^3.0.0"
  1914 +
  1915 +"@vuedx/typecheck@^0.4.0":
  1916 + version "0.4.0"
  1917 + resolved "https://registry.npmjs.org/@vuedx/typecheck/-/typecheck-0.4.0.tgz#331124e2ae96cac066943e56d4eb67d44da1274e"
  1918 + integrity sha512-2GOXVpyD/bDPjz+ZQK/ltN06XuA+2s3Tq2n7wpUx7ws9vzyhVJQzgUv6SL1LKu04x+qZMFkBX2Q0vMfaQqh5Eg==
1800 dependencies: 1919 dependencies:
1801 - "@vue/compiler-core" "*"  
1802 - "@vue/compiler-sfc" "*"  
1803 - "@vuedx/typescript-plugin-vue" "0.2.4-0"  
1804 - "@vuedx/vue-virtual-textdocument" "0.2.4-0" 1920 + "@vuedx/typescript-plugin-vue" "0.4.0"
  1921 + "@vuedx/vue-virtual-textdocument" "0.4.0"
1805 chalk "^4.1.0" 1922 chalk "^4.1.0"
  1923 + fast-glob "^3.2.4"
1806 minimist "^1.2.5" 1924 minimist "^1.2.5"
  1925 + typescript "^4.0.3"
1807 1926
1808 -"@vuedx/typescript-plugin-vue@0.2.4-0", "@vuedx/typescript-plugin-vue@^0.2.4-0":  
1809 - version "0.2.4-0"  
1810 - resolved "https://registry.npmjs.org/@vuedx/typescript-plugin-vue/-/typescript-plugin-vue-0.2.4-0.tgz#e07485139e28de823e5153d96a2f71e82d0f75f2"  
1811 - integrity sha512-BB5S29B2JRmmaglM8gJD/VT0Ika9RUnZYUCOMCopHCItyTbFC7RLJkIZg9rZS77R87/alD5W316WxqgE8C9XYA==  
1812 - dependencies:  
1813 - "@vue/compiler-core" "^3.0.0-rc.5"  
1814 - "@vuedx/analyze" "0.2.4-0"  
1815 - "@vuedx/template-ast-types" "0.2.4-0"  
1816 - "@vuedx/vue-virtual-textdocument" "0.2.4-0" 1927 +"@vuedx/typescript-plugin-vue@0.4.0", "@vuedx/typescript-plugin-vue@^0.4.0":
  1928 + version "0.4.0"
  1929 + resolved "https://registry.npmjs.org/@vuedx/typescript-plugin-vue/-/typescript-plugin-vue-0.4.0.tgz#4780912f5915e65adfcae4764229918366723ac9"
  1930 + integrity sha512-3VTo19ZhnqZbnu3RGRxDJmEw7KI4e+CvXGhrlrjTgqsxgS10yfqn44cgYXF7et4iv/5RRQJjFXUO6Uvla52e8g==
  1931 + dependencies:
  1932 + "@intlify/core" "^9.0.0-beta.15"
  1933 + "@vuedx/analyze" "0.4.0"
  1934 + "@vuedx/compiler-sfc" "0.4.0"
  1935 + "@vuedx/projectconfig" "0.4.0"
  1936 + "@vuedx/template-ast-types" "0.4.0"
  1937 + "@vuedx/vue-virtual-textdocument" "0.4.0"
1817 de-indent "^1.0.2" 1938 de-indent "^1.0.2"
  1939 + json5 "^2.1.3"
1818 quick-lru "^5.1.1" 1940 quick-lru "^5.1.1"
1819 - typescript "^3.9.7"  
1820 vscode-uri "^2.1.2" 1941 vscode-uri "^2.1.2"
  1942 + vscode-web-custom-data "^0.3.2"
1821 1943
1822 -"@vuedx/vue-virtual-textdocument@0.2.4-0":  
1823 - version "0.2.4-0"  
1824 - resolved "https://registry.npmjs.org/@vuedx/vue-virtual-textdocument/-/vue-virtual-textdocument-0.2.4-0.tgz#ea5eb9d17b83b1ebf1e5b4e7313634bc2c4c2a54"  
1825 - integrity sha512-eCgyvN5/O27UWlAohwuHzlPftoxEIrEz6zEDncXKFb7Gzzp5EoNlptXN16tJoYGHi1duz4aMnEg6p5xoBSqArQ== 1944 +"@vuedx/vue-virtual-textdocument@0.4.0":
  1945 + version "0.4.0"
  1946 + resolved "https://registry.npmjs.org/@vuedx/vue-virtual-textdocument/-/vue-virtual-textdocument-0.4.0.tgz#e10bcff51f43f3f64790e39f09dfa767e91b8e16"
  1947 + integrity sha512-z4yR5CTG3HtrctAPosbbI3+xldPGzJ4nJHXA7s4k60iIxKruLzlzWbjHtvl9VSekAzRcAr0slJifr5wE47L1QQ==
1826 dependencies: 1948 dependencies:
1827 - "@vue/compiler-core" "^3.0.0-rc.5"  
1828 - "@vue/compiler-sfc" "^3.0.0-rc.5"  
1829 - "@vuedx/analyze" "0.2.4-0"  
1830 - "@vuedx/compiler-tsx" "0.2.4-0" 1949 + "@vuedx/analyze" "0.4.0"
  1950 + "@vuedx/compiler-sfc" "0.4.0"
  1951 + "@vuedx/compiler-tsx" "0.4.0"
  1952 + source-map "^0.6.1"
1831 vscode-languageserver-textdocument "^1.0.1" 1953 vscode-languageserver-textdocument "^1.0.1"
1832 vscode-uri "^2.1.2" 1954 vscode-uri "^2.1.2"
1833 1955
@@ -2621,7 +2743,7 @@ colorette@^1.2.1: @@ -2621,7 +2743,7 @@ colorette@^1.2.1:
2621 resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" 2743 resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
2622 integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== 2744 integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
2623 2745
2624 -commander@*, commander@^6.0.0, commander@^6.2.0: 2746 +commander@*, commander@^6.2.0:
2625 version "6.2.0" 2747 version "6.2.0"
2626 resolved "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75" 2748 resolved "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75"
2627 integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q== 2749 integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==
@@ -2636,6 +2758,11 @@ commander@^4.1.1: @@ -2636,6 +2758,11 @@ commander@^4.1.1:
2636 resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" 2758 resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
2637 integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 2759 integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
2638 2760
  2761 +commander@^6.1.0:
  2762 + version "6.2.1"
  2763 + resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
  2764 + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
  2765 +
2639 commander@~2.14.1: 2766 commander@~2.14.1:
2640 version "2.14.1" 2767 version "2.14.1"
2641 resolved "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" 2768 resolved "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
@@ -4929,7 +5056,7 @@ json5@^1.0.1: @@ -4929,7 +5056,7 @@ json5@^1.0.1:
4929 dependencies: 5056 dependencies:
4930 minimist "^1.2.0" 5057 minimist "^1.2.0"
4931 5058
4932 -json5@^2.1.2: 5059 +json5@^2.1.2, json5@^2.1.3:
4933 version "2.1.3" 5060 version "2.1.3"
4934 resolved "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" 5061 resolved "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
4935 integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== 5062 integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
@@ -7870,12 +7997,7 @@ typedarray-to-buffer@^3.1.5: @@ -7870,12 +7997,7 @@ typedarray-to-buffer@^3.1.5:
7870 dependencies: 7997 dependencies:
7871 is-typedarray "^1.0.0" 7998 is-typedarray "^1.0.0"
7872 7999
7873 -typescript@^3.9.7:  
7874 - version "3.9.7"  
7875 - resolved "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"  
7876 - integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==  
7877 -  
7878 -typescript@^4.1.3: 8000 +typescript@^4.0.3, typescript@^4.1.3:
7879 version "4.1.3" 8001 version "4.1.3"
7880 resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" 8002 resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
7881 integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== 8003 integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
@@ -8096,10 +8218,10 @@ vite-plugin-purge-icons@^0.4.5: @@ -8096,10 +8218,10 @@ vite-plugin-purge-icons@^0.4.5:
8096 "@purge-icons/generated" "^0.4.1" 8218 "@purge-icons/generated" "^0.4.1"
8097 rollup-plugin-purge-icons "^0.4.5" 8219 rollup-plugin-purge-icons "^0.4.5"
8098 8220
8099 -vite-plugin-pwa@^0.2.0:  
8100 - version "0.2.0"  
8101 - resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.2.0.tgz#e9368530c97537bdad7279f05de061ab9b024cce"  
8102 - integrity sha512-OBNhlSqvqH9af9i8HsetmaRTrUjit3UP0rx33Sr0iBapM0gtuAmTjS4JPdSM54cGC1aVaIC3Rn3sY9wL0uxBrw== 8221 +vite-plugin-pwa@^0.2.1:
  8222 + version "0.2.1"
  8223 + resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.2.1.tgz#67e569ac7d5af4b094c6c41b50d06955dd09ef6a"
  8224 + integrity sha512-d1Tw5O3dZjAVVS9wZTI1V6gw7m2wK0LJQ/K+D5I00i6kpuJObPcX5nIrPyPJsKYAm53AU2VwnAMB5thL7MGSMw==
8103 dependencies: 8225 dependencies:
8104 debug "^4.3.2" 8226 debug "^4.3.2"
8105 fast-glob "^3.2.4" 8227 fast-glob "^3.2.4"
@@ -8176,6 +8298,11 @@ vscode-uri@^2.1.2: @@ -8176,6 +8298,11 @@ vscode-uri@^2.1.2:
8176 resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c" 8298 resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
8177 integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A== 8299 integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==
8178 8300
  8301 +vscode-web-custom-data@^0.3.2:
  8302 + version "0.3.2"
  8303 + resolved "https://registry.npmjs.org/vscode-web-custom-data/-/vscode-web-custom-data-0.3.2.tgz#62a5a924397d8056c5524ff0ff8f14eb815b7066"
  8304 + integrity sha512-GGZ99dJbARyh6rv03dXZImGlP5WvNG382A3nIt0yX1uyqBa558L/klHWcgEJzcVkG4t16OQWwPedMR3JkeD2Qg==
  8305 +
8179 vue-demi@latest: 8306 vue-demi@latest:
8180 version "0.4.5" 8307 version "0.4.5"
8181 resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.4.5.tgz#ea422a4468cb6321a746826a368a770607f87791" 8308 resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.4.5.tgz#ea422a4468cb6321a746826a368a770607f87791"