Hooks
Provides useReactiveForm and useDyForm and useDecorateForm to quickly update input values and manage form state.
1. useReactiveForm
Used to wrap a DyFormItem[] with shallowReactive in a unified way.
Signature
export function useReactiveForm<T extends Record<string, any>, U = any>(
items: DyFormItem<T, U>[],
isReactive: boolean = true
): DyFormItem<T, U>[]参数
items:form item array (each item is aDyFormItem)isReactive:whether to wrap withshallowReactive(defaulttrue; passfalseto return the original array as-is)
Example
type FormRow = { username: string; password: string }
const formItems = useReactiveForm<FormRow>([
{
key: "username",
label: "Name",
value: ref<string | null>(null),
required: true,
render2: f => renderInput(f.value, {}, f),
},
{
key: "password",
label: "Password",
value: ref<string | null>(null),
required: true,
render2: f => renderInput(f.value, {showPasswordOn: "click"}, f),
},
{
key: "sex",
label: "Sex",
value: ref<number | null>(null),
render2: f => renderRadioGroup(f.value, [
{label: 'male', value: 0}, {label: 'female', value: 1},
], {}, f),
},
])2. useDyForm
Provides external control for a DyFormItem[]: disable, hide, set/get values, reset, etc.
Signature
export function useDyForm<Row extends Record<string, any>>(
items: DyFormItem<Row>[] | Ref<DyFormItem<Row>[]>
)Return Functions
setDisabled(disabled, keys?):batch disable/enable (if keys is omitted, applies to all)setHidden(hidden, keys?):batch hide/show (if keys is omitted, applies to all)setValue(key, value):set a single field valuesetValues(patch):batch set field valuesgetValue(key):get theDyFormItemobject for a given fieldgetValues(keys?):get form values (if keys is omitted, returns all; otherwise returns specified fields)onReset(value=null):reset all field values to the same value (defaultnull)getItem(key): Get theDyFormIteminstance for the specified field.setItem(key, {}): Set non-valueproperties for the specified field.setItems([[key, {}]]): Batch set non-valueproperties for specified fields.updateKeys([['username', 'name']]): Replace keys.
API usage example
Assume:
type FormRow = { username: string; password: string }
const useForm = useDyForm<FormRow>(formItems)1. Batch disable / enable
useForm.setDisabled(true) // disable all
useForm.setDisabled(true, ["username"]) // disable only username
useForm.setDisabled(false, ["password"]) // enable only password2. Batch hide / show
useForm.setHidden(true, ["username"]) // hide username
useForm.setHidden(false, ["username"]) // show username3. Set values (single / batch)
useForm.setValue("username", "zhangsan")
useForm.setValues({
username: "naive-ui",
password: "520",
})4. Get values
const all = useForm.getValues()
const part = useForm.getValues(["username"])
const part2 = useForm.getValue('username')5. Reset
useForm.onReset() // set all to null
useForm.onReset("") // set all to empty string6. Modify other values
useForm.setItem('username', {placeholder: 'please input username'}) // modify placeholder
useForm.setItems([
['username', {placeholder: 'please input username'}],
['password', {hidden: true}],
]) // Modify all properties of `DyFormItem` except `value`.7. Modify key
This method modifies keys directly, which can easily cause confusion. Use with caution.
useForm.updateKeys([['sex', 'gender']])3. useDecorateForm
Simplifies the render2 function by providing render types. It iterates and processes items, then wraps the DyFormItem[] with shallowReactive in a unified way.
Import from the UI adapter you choose, for example: import { useDecorateForm } from "dynamicformdjx/naiveUi";
Signature
// type
type RenderType =
| "renderInput"
| "renderSelect"
| "renderPopSelect"
| "renderTreeSelect"
| "renderRadioGroup"
| "renderRadioButtonGroup"
| "renderCheckboxGroup"
| "renderSwitch"
| "renderDatePicker"
| "renderTimePicker"
type DecorateDyFormItem<Row extends Record<string, any>, RuleT = any> =
Omit<DyFormItem<Row, RuleT>, "value"> & {
value: DyFormItem<Row, RuleT>["value"] | any | null
renderType?: RenderType
renderProps?: Record<string, any>
}
// function
export function useDecorateForm<Row extends Record<string, any>, RuleT = any>(
items: DecorateDyFormItem<Row, RuleT>[],
isReactive = true
): DyFormItem<T, U>[]Parameters
items:form item array (each item is aDecorateDyFormItem)isReactive:whether to wrap withshallowReactive(defaulttrue; passfalseto return the original array as-is)
DecorateDyFormItem
renderType:render type (from helpers provided in renderForm, e.g.("renderInput"| "renderSelect"| " renderPopSelect"| "renderTreeSelect"| " renderRadioGroup"| "renderRadioButtonGroup"| "renderCheckboxGroup"| "renderSwitch"| "renderDatePicker"| " renderTimePicker")renderProps:render props passed to the selected renderType, e.g. showPasswordOn: "click" forrenderInput
Example
type FormRow = { username: string; job: number }
const formItems = useDecorateForm<FormRow>([
{
key: "username",
label: "Name",
value: null,
required: true,
renderType: 'renderInput'
},
{
key: "job",
label: "Role",
value: null,
required: true,
options: ['Frontend', 'Backend'].map((label, value) => ({label, value})),
renderType: 'renderSelect'
},
])4. usePagination
Pagination hook that provides basic pagination configuration.
Signature
export type PageModal = {
pageSize: number
pageNo: number
total: number
}
export type ZealPagination = {
showSizePicker: boolean
pageCount?: number
pageSizes: number[]
pageSlot?: number
onChange: () => void
onPageSizeChange: () => void
setTotalSize: (totalSize: number) => void
layout?: string
} & PageModal
export function usePagination(
cb?: () => void,
options?: Partial<ZealPagination>
): ZealPaginationParameters
cb: Request callback. It will be triggered when the internal page number or page size changes.options: Initial pagination configuration. The passed options will be merged with the default values.
Example
const pagination = usePagination(fetchData)
function fetchData() {
const {pageNo, pageSize} = pagination
// ...
}5. useWindowSize
Listens to window size changes and provides the updated width and height.
Signature
type SizeObjType = {
isMobile: boolean
width: number
height: number
}
export function useWindowSize(
mobileWidth: number,
delay: number
): SizeObjTypeParameters
mobileWidth: Maximum width for mobile devices. Whenwidthis smaller than this value,isMobilewill betrue. Default is756.delay: Delay time in milliseconds. When the window size changes, the new value will be returned after this delay. Default is500.
Example
const {isMobile, width, height} = useWindowSize()6. useObserverSize
Calculates the remaining height inside the content area.
Signature
export function useObserverSize<T extends VueComponentCtor>(ct: T): {
wrapRef,
cardRef,
restRef,
tableHeight
}Parameters
ct: Component constructor. Internally, it only checksct.name === 'ElCard' ? 'el' : 'n'to calculate the remaining content height.
Example
Using ElCard as an example
<script setup lang="ts">
import {useObserverSize} from "dynamicformdjx";
import {ElCard} from "element-plus";
const {wrapRef, cardRef, restRef, tableHeight} = useObserverSize(ElCard);
</script>
<template>
<div class="container" ref="wrapRef">
<el-card ref="cardRef">
<template #header>
useObserverSize Test
</template>
<div
class="content"
:style="{
height: tableHeight + 'px'
}"
>
<p>tableHeight {{ tableHeight }}</p>
</div>
</el-card>
<div class="rest" ref="restRef"></div>
</div>
</template>
<style scoped>
.container {
height: calc(100vh - 40px);
}
</style>