diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 8769ed2c4f70c77e68df1286c11be8ff338a2570..87623d3007a40d544735d52c8cf5f0d895d9cd33 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -23,6 +23,7 @@ - 修复表格开启搜索表单折叠问题 - 修复表格 size 为 samll 时候,fixed 列样式问题 - 修复多标签页关闭报错问题 +- 修复 message 类型错误 ## 2.0.0-rc.7 (2020-10-31) diff --git a/src/components/Container/src/collapse/CollapseHeader.vue b/src/components/Container/src/collapse/CollapseHeader.vue index 9dab03e41b486ba362c03f479b5b0e9b27f6be14..e970deb3c35d6e90dc835db0dcb64e9bbbb080c4 100644 --- a/src/components/Container/src/collapse/CollapseHeader.vue +++ b/src/components/Container/src/collapse/CollapseHeader.vue @@ -11,22 +11,15 @@
- +
diff --git a/src/hooks/core/asyncComputed.ts b/src/hooks/core/asyncComputed.ts new file mode 100644 index 0000000000000000000000000000000000000000..a368181ec4f5a800f9673d132c29c9a3b23794a1 --- /dev/null +++ b/src/hooks/core/asyncComputed.ts @@ -0,0 +1,56 @@ +import { ref, watchEffect, Ref } from 'vue'; + +/** + * Handle overlapping async evaluations + * + * @param cancelCallback The provided callback is invoked when a re-evaluation of the computed value is triggered before the previous one finished + */ +export type AsyncComputedOnCancel = (cancelCallback: () => void) => void; + +/** + * A two-item tuple with the first item being a ref to the computed value and the second item holding a boolean ref, indicating whether the async computed value is currently (re-)evaluated + */ +export type AsyncComputedResult = [Ref, Ref]; + +/** + * Create an asynchronous computed dependency + * + * @param evaluationCallback The promise-returning callback which generates the computed value + * @param defaultValue A default value, used until the first evaluation finishes + */ +export function asyncComputed( + evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise, + defaultValue?: T +): AsyncComputedResult { + let counter = 0; + const current = ref(defaultValue) as Ref; + const evaluating = ref(false); + + watchEffect(async (onInvalidate: Fn) => { + counter++; + const counterAtBeginning = counter; + let hasFinished = false; + + try { + // Defer initial setting of `evaluating` ref + // to avoid having it as a dependency + Promise.resolve().then(() => { + evaluating.value = true; + }); + + const result = await evaluationCallback((cancelCallback) => { + onInvalidate(() => { + evaluating.value = false; + if (!hasFinished) cancelCallback(); + }); + }); + + if (counterAtBeginning === counter) current.value = result; + } finally { + evaluating.value = false; + hasFinished = true; + } + }); + + return [current, evaluating]; +} diff --git a/src/hooks/core/types.ts b/src/hooks/core/types.ts index 6a5f2e6e0fd47d167178c2ba856ad16dcfa1326d..fd493201d1fb41408545cd3b730e966d86369a6d 100644 --- a/src/hooks/core/types.ts +++ b/src/hooks/core/types.ts @@ -1,5 +1,5 @@ import type { VNode, Ref } from 'vue'; -import type { ModalOptions } from 'ant-design-vue/types/modal'; +import type { ModalFuncProps } from 'ant-design-vue/lib/modal/index'; export type Fn = () => T; export type AnyFn = (...arg: any) => T; @@ -86,7 +86,7 @@ export interface MessageOptions { /** Set the distance to the top of viewport. Default is 20 px. */ offset?: number; } -export interface ModalOptionsEx extends Omit { +export interface ModalOptionsEx extends Omit { iconType: 'warning' | 'success' | 'error' | 'info'; } export type ModalOptionsPartial = Partial & Pick; diff --git a/src/hooks/web/useMessage.tsx b/src/hooks/web/useMessage.tsx index 8bedc6ec37dddd76c33a254c9d10b7db6ad3383c..7a8631b9c30bfc01a0e4fbf481866906f0aef380 100644 --- a/src/hooks/web/useMessage.tsx +++ b/src/hooks/web/useMessage.tsx @@ -1,11 +1,19 @@ import type { ModalOptionsEx, ModalOptionsPartial } from '/@/hooks/core/types'; +import type { ModalFunc, ModalFuncProps } from 'ant-design-vue/lib/modal/Modal'; import { Modal, message as Message, notification } from 'ant-design-vue'; import { InfoCircleFilled, CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons-vue'; -import { ModalOptions, ModalConfirm } from 'ant-design-vue/types/modal'; import { useSetting } from '/@/hooks/core/useSetting'; +interface ConfirmOptions { + info: ModalFunc; + success: ModalFunc; + error: ModalFunc; + warn: ModalFunc; + warning: ModalFunc; +} + const { projectSetting } = useSetting(); function getIcon(iconType: string) { @@ -20,22 +28,22 @@ function getIcon(iconType: string) { } } function renderContent({ content }: Pick) { - return
${content}
`}>; + return
${content as string}
`}>; } /** * @description: Create confirmation box */ -function createConfirm(options: ModalOptionsEx): ModalConfirm { +function createConfirm(options: ModalOptionsEx): ConfirmOptions { const iconType = options.iconType || 'warning'; Reflect.deleteProperty(options, 'iconType'); - const opt: ModalOptions = { + const opt: ModalFuncProps = { centered: true, icon: getIcon(iconType), ...projectSetting.messageSetting, ...options, }; - return Modal.confirm(opt); + return Modal.confirm(opt) as any; } const baseOptions = { okText: '确定', diff --git a/src/utils/index.ts b/src/utils/index.ts index 45dfb8390df07e0faca0813de54c3cbba7df1a6f..e5ecd506bd5e5feae438770ff0b2bc76e5956e94 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,7 @@ +export const timestamp = () => +Date.now(); +export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n)); +export const noop = () => {}; +export const now = () => Date.now(); /** * @description: Set ui mount node */