diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 7551adf31b58c96f90ba35f12cc7eb28ed5ffe7c..cfc48dc90047675ce7ebbdf0c077e23af29b5e32 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -11,6 +11,7 @@ - form: 新增`suffix`属性,用于配置后缀内容 - form: 新增远程下拉`ApiSelect`及示例 - form: 新增`autoFocusFirstItem`配置。用于配置是否聚焦表单第一个输入框 +- useForm: 支持动态改变参数。可以传入`Ref`类型与`Computed`类型进行动态更改 ### ⚡ Performance Improvements @@ -18,7 +19,7 @@ ### 🎫 Chores -- 升级`ant-design-vue`到`2.0.0-rc.6` +- 升级`ant-design-vue`到`2.0.0-rc.7` ### 🐛 Bug Fixes diff --git a/package.json b/package.json index 4796840453c44d8d64ffb6e3b0bc3d3a9457f600..8508249103908cc46c0c2155ec03cbef08181878 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "dependencies": { "@iconify/iconify": "^2.0.0-rc.4", "@vueuse/core": "^4.0.1", - "ant-design-vue": "^2.0.0-rc.6", + "ant-design-vue": "^2.0.0-rc.7", "apexcharts": "^3.23.0", "axios": "^0.21.1", "crypto-es": "^1.2.6", diff --git a/src/components/Form/src/BasicForm.vue b/src/components/Form/src/BasicForm.vue index fec566c9aa94f4aa6f3e315a3023f8b9b3fc8478..35a898a5ee9ab0409cdc622b57d3998f117d17c0 100644 --- a/src/components/Form/src/BasicForm.vue +++ b/src/components/Form/src/BasicForm.vue @@ -31,14 +31,24 @@ import type { AdvanceState } from './types/hooks'; import type { CSSProperties, Ref, WatchStopHandle } from 'vue'; - import { defineComponent, reactive, ref, computed, unref, onMounted, watch, toRefs } from 'vue'; + import { + defineComponent, + reactive, + ref, + computed, + unref, + onMounted, + watch, + toRefs, + toRaw, + } from 'vue'; import { Form, Row } from 'ant-design-vue'; import FormItem from './components/FormItem'; import FormAction from './components/FormAction.vue'; import { dateItemType } from './helper'; import moment from 'moment'; - import { cloneDeep } from 'lodash-es'; + // import { cloneDeep } from 'lodash-es'; import { deepMerge } from '/@/utils'; import { useFormValues } from './hooks/useFormValues'; @@ -76,7 +86,7 @@ // Get the basic configuration of the form const getProps = computed( (): FormProps => { - return deepMerge(cloneDeep(props), unref(propsRef)); + return { ...props, ...unref(propsRef) } as FormProps; } ); diff --git a/src/components/Form/src/components/ApiSelect.vue b/src/components/Form/src/components/ApiSelect.vue index 6463ff190c49ab24f3e334e19092a626d8790f92..60e40e651aaf012a0e3fe8ae8dbccbf0740d3509 100644 --- a/src/components/Form/src/components/ApiSelect.vue +++ b/src/components/Form/src/components/ApiSelect.vue @@ -38,7 +38,7 @@ type: String as PropType, }, api: { - type: Function as PropType<(arg: Recordable) => Promise>, + type: Function as PropType<(arg?: Recordable) => Promise>, default: null, }, params: { diff --git a/src/components/Form/src/hooks/useForm.ts b/src/components/Form/src/hooks/useForm.ts index 4ba2ba91aa7917819784a2cbed58a9650d4d0953..6d159890f0a4c0593fec37f70179d04e4277975a 100644 --- a/src/components/Form/src/hooks/useForm.ts +++ b/src/components/Form/src/hooks/useForm.ts @@ -1,15 +1,19 @@ -import { ref, onUnmounted, unref, nextTick } from 'vue'; +import { ref, onUnmounted, unref, nextTick, watchEffect } from 'vue'; import { isInSetup } from '/@/utils/helper/vueHelper'; import { isProdMode } from '/@/utils/env'; import { error } from '/@/utils/log'; +import { getDynamicProps } from '/@/utils'; import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form'; import type { NamePath } from 'ant-design-vue/lib/form/interface'; +import type { DynamicProps } from '/@/types/utils'; export declare type ValidateFields = (nameList?: NamePath[]) => Promise; -export function useForm(props?: Partial): UseFormReturnType { +type Props = Partial>; + +export function useForm(props?: Props): UseFormReturnType { isInSetup(); const formRef = ref>(null); @@ -25,6 +29,7 @@ export function useForm(props?: Partial): UseFormReturnType { await nextTick(); return form as FormActionType; } + function register(instance: FormActionType) { isProdMode() && onUnmounted(() => { @@ -34,8 +39,12 @@ export function useForm(props?: Partial): UseFormReturnType { if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return; formRef.value = instance; - props && instance.setProps(props); + loadedRef.value = true; + + watchEffect(() => { + props && instance.setProps(getDynamicProps(props)); + }); } const methods: FormActionType = { diff --git a/src/components/Form/src/hooks/useFormEvents.ts b/src/components/Form/src/hooks/useFormEvents.ts index 7232f4f642083f538e2ee083672bfdf3245d6168..f6e548664a06a9094aa4f7102dc51ed2e4e22ea2 100644 --- a/src/components/Form/src/hooks/useFormEvents.ts +++ b/src/components/Form/src/hooks/useFormEvents.ts @@ -178,12 +178,10 @@ export function useFormEvents({ } async function validateFields(nameList?: NamePath[] | undefined) { - const res = await unref(formElRef)?.validateFields(nameList || []); - return res; + return unref(formElRef)?.validateFields(nameList); } - async function validate(nameList?: NamePath[] | undefined) { - return await unref(formElRef)?.validate(nameList || []); + return await unref(formElRef)?.validate(nameList); } async function clearValidate(name?: string | string[]) { diff --git a/src/components/Form/src/hooks/useLabelWidth.ts b/src/components/Form/src/hooks/useLabelWidth.ts index ae4274dc24864476991d4f3ada2320bf61434714..fb96ee3df1ddf89c53532bf0ee0c86387f97289c 100644 --- a/src/components/Form/src/hooks/useLabelWidth.ts +++ b/src/components/Form/src/hooks/useLabelWidth.ts @@ -18,6 +18,9 @@ export function useItemLabelWidth(schemaItemRef: Ref, propsRef: Ref< // If labelWidth is set globally, all items setting if ((!globalLabelWidth && !labelWidth && !globalLabelCol) || disabledLabelWidth) { + labelCol.style = { + textAlign: 'left', + }; return { labelCol, wrapperCol }; } let width = labelWidth || globalLabelWidth; @@ -27,6 +30,7 @@ export function useItemLabelWidth(schemaItemRef: Ref, propsRef: Ref< if (width) { width = isNumber(width) ? `${width}px` : width; } + return { labelCol: { style: { width }, ...col }, wrapperCol: { style: { width: `calc(100% - ${width})` }, ...wrapCol }, diff --git a/src/components/Table/src/BasicTable.vue b/src/components/Table/src/BasicTable.vue index e238fdef60f93bf9f06314ebe94ea84061969316..4b9023f5245cfe0e9fa9a5918fd1aba7f2938b73 100644 --- a/src/components/Table/src/BasicTable.vue +++ b/src/components/Table/src/BasicTable.vue @@ -68,8 +68,9 @@ import { useEventListener } from '/@/hooks/event/useEventListener'; import { basicProps } from './props'; import { ROW_KEY } from './const'; - import './style/index.less'; import { useExpose } from '/@/hooks/core/useExpose'; + + import './style/index.less'; export default defineComponent({ props: basicProps, components: { Table, BasicForm }, @@ -87,6 +88,12 @@ } as BasicTableProps; }); + // const getProps = computed( + // (): FormProps => { + // return deepMerge(toRaw(props), unref(innerPropsRef)); + // } + // ); + const { loadingRef } = useLoading(getMergeProps); const { getPaginationRef, setPagination } = usePagination(getMergeProps); const { getColumnsRef, setColumns } = useColumns(getMergeProps, getPaginationRef); @@ -299,8 +306,8 @@ loadingRef.value = loading; }, setProps, - getSize: (): SizeType => { - return unref(getBindValues).size; + getSize: () => { + return unref(getBindValues).size as SizeType; }, }; diff --git a/src/components/Table/src/components/EditTableHeaderIcon.vue b/src/components/Table/src/components/EditTableHeaderIcon.vue index 2666a27905dd58b029954fc7a73ea8586fb2689b..0cc00fa4922aebca47c51a994200d3f2638049d0 100644 --- a/src/components/Table/src/components/EditTableHeaderIcon.vue +++ b/src/components/Table/src/components/EditTableHeaderIcon.vue @@ -16,6 +16,5 @@ default: '', }, }, - setup() {}, }); diff --git a/src/components/Table/src/components/TableSetting.vue b/src/components/Table/src/components/TableSetting.vue index 3fd5f8fcc08ae3c651bfa8c9c402749620c67119..16fbdb486b2238f80e1c62a60b4be835d41ea096 100644 --- a/src/components/Table/src/components/TableSetting.vue +++ b/src/components/Table/src/components/TableSetting.vue @@ -90,7 +90,6 @@ SettingOutlined, } from '@ant-design/icons-vue'; import { useFullscreen } from '/@/hooks/web/useFullScreen'; - import type { SizeType, TableSetting } from '../types/table'; import { useI18n } from '/@/hooks/web/useI18n'; @@ -150,6 +149,7 @@ init(); } }); + function init() { let ret: Options[] = []; table.getColumns({ ignoreIndex: true, ignoreAction: true }).forEach((item) => { diff --git a/src/components/Table/src/components/TableTitle.vue b/src/components/Table/src/components/TableTitle.vue index 4d98075e5d58d5fb5d8975517c44396b12295d9d..1dffb283f05daa414c9e26c5c201534ba0c8b9e3 100644 --- a/src/components/Table/src/components/TableTitle.vue +++ b/src/components/Table/src/components/TableTitle.vue @@ -13,10 +13,10 @@ components: { BasicTitle }, props: { title: { - type: [Function, String] as PropType string)>, + type: [Function, String] as PropType string)>, }, getSelectRows: { - type: Function as PropType<() => any[]>, + type: Function as PropType<() => Recordable[]>, }, helpMessage: { type: [String, Array] as PropType, diff --git a/src/components/Table/src/components/renderExpandIcon.tsx b/src/components/Table/src/components/renderExpandIcon.tsx index cda72a4387c14477bbef463c07305a6d5a186b85..d84df11fd9cbe8d19cbb0f0f0bcb0a0a66f5680b 100644 --- a/src/components/Table/src/components/renderExpandIcon.tsx +++ b/src/components/Table/src/components/renderExpandIcon.tsx @@ -1,7 +1,7 @@ import { BasicArrow } from '/@/components/Basic'; export default () => { - return (props: any) => { + return (props: Recordable) => { return ( { diff --git a/src/components/Table/src/hooks/useTable.ts b/src/components/Table/src/hooks/useTable.ts index 3990d481209805d911d216eda82b479baf1d67fc..cb5ccd831a96f7946dd832054e5b15799f85df5e 100644 --- a/src/components/Table/src/hooks/useTable.ts +++ b/src/components/Table/src/hooks/useTable.ts @@ -1,24 +1,24 @@ import type { BasicTableProps, TableActionType, FetchParams, BasicColumn } from '../types/table'; import type { PaginationProps } from '../types/pagination'; -import { ref, getCurrentInstance, onUnmounted, unref } from 'vue'; +import { ref, onUnmounted, unref } from 'vue'; import { isProdMode } from '/@/utils/env'; +import { isInSetup } from '/@/utils/helper/vueHelper'; export function useTable( tableProps?: Partial ): [(instance: TableActionType) => void, TableActionType] { - if (!getCurrentInstance()) { - throw new Error('Please put useTable function in the setup function!'); - } + isInSetup(); - const tableRef = ref(null); - const loadedRef = ref(false); + const tableRef = ref>(null); + const loadedRef = ref>(false); function register(instance: TableActionType) { onUnmounted(() => { tableRef.value = null; loadedRef.value = null; }); + if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) { return; } diff --git a/src/layouts/default/header/components/lock/LockAction.tsx b/src/layouts/default/header/components/lock/LockAction.tsx index b3d3d99106465fb0ff91dcaf44eb4fd50ae1a4bb..51483b5adaa8e8dd75261e9bdab8fbeaba1b6158 100644 --- a/src/layouts/default/header/components/lock/LockAction.tsx +++ b/src/layouts/default/header/components/lock/LockAction.tsx @@ -57,7 +57,7 @@ export default defineComponent({

{userStore.getUserInfoState.realName}

- +
- +
diff --git a/src/types/utils.ts b/src/types/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..6500d44729c042cef5aaf11b10d599bac6b7f68a --- /dev/null +++ b/src/types/utils.ts @@ -0,0 +1,5 @@ +import type { ComputedRef, Ref } from 'vue'; + +export type DynamicProps = { + [P in keyof T]: Ref | T[P] | ComputedRef; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index b24685fa05af64b91328bd2c254e8fa0fc58d549..c02fdad31df3df3ff9e6de3817937ffc47146f80 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ export const timestamp = () => +Date.now(); +import { unref } from 'vue'; import { isObject } from '/@/utils/is'; export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n)); export const noop = () => {}; @@ -76,3 +77,14 @@ export function openWindow( window.open(url, target, feature.join(',')); } + +// dynamic use hook props +export function getDynamicProps(props: T): Partial { + const ret: Recordable = {}; + + Object.keys(props).map((key) => { + ret[key] = unref((props as Recordable)[key]); + }); + + return ret as Partial; +} diff --git a/src/views/demo/form/UseForm.vue b/src/views/demo/form/UseForm.vue index 622616239b43bedfe01204a722acd895ca986083..1b22c928dce69f534c9fa5e452224b9545c7aeb1 100644 --- a/src/views/demo/form/UseForm.vue +++ b/src/views/demo/form/UseForm.vue @@ -162,6 +162,7 @@ components: { BasicForm, CollapseContainer }, setup() { const { createMessage } = useMessage(); + const [register, { setProps }] = useForm({ labelWidth: 120, schemas, @@ -172,7 +173,7 @@ return { register, schemas, - handleSubmit: (values: any) => { + handleSubmit: (values: Recordable) => { createMessage.success('click search,values:' + JSON.stringify(values)); }, setProps, diff --git a/src/views/demo/page/form/high/index.vue b/src/views/demo/page/form/high/index.vue index 5269f7df27edbb63da483dd7600029eb8c10f15f..9846e2ade36e06fa3b62bbdd5584c4174f7de443 100644 --- a/src/views/demo/page/form/high/index.vue +++ b/src/views/demo/page/form/high/index.vue @@ -6,10 +6,10 @@
- + - + diff --git a/yarn.lock b/yarn.lock index 8c41c80d94df9014cfb79b2412bd116756350ec8..79d6cb939d3c2d7467c089b2dfdbd5a03591e5cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1956,10 +1956,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ant-design-vue@^2.0.0-rc.6: - version "2.0.0-rc.6" - resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.6.tgz#f25f61cde1c75c32a78b536751731c0b223b6590" - integrity sha512-NRxzIC4CSM56MXYHdg3K2oTc+pkcSJd6BJtIBCxUsbFfbBGp+F7ei7C1bQDdHHos3o/Oe2iqGwzfrZ7+Ot2Uew== +ant-design-vue@^2.0.0-rc.7: + version "2.0.0-rc.7" + resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.7.tgz#5d83a7f13275574ec1fc1ea8c1fe8d9aa6de067c" + integrity sha512-QMStvwaLfV1Q3RaQ8D926aCkW6iqWBHXlNv7dBdTPvU8eeFXPaPKenLu1OTpSi+wpCncJqgumFOEcENPvh0nKw== dependencies: "@ant-design-vue/use" "^0.0.1-0" "@ant-design/icons-vue" "^5.1.7"