feat: 更新 useSafeNForm 组件,优化类型定义 [skip ci]
This commit is contained in:
@@ -10,6 +10,7 @@ const { formValue, SafeNForm, SafeNFormItem, formRef } = useSafeNForm({
|
||||
*/
|
||||
user: {
|
||||
name: '',
|
||||
age: 0,
|
||||
},
|
||||
phone: '',
|
||||
},
|
||||
@@ -19,7 +20,7 @@ function handleSetUserName() {
|
||||
set(formValue.value, 'user.name', 'Alice');
|
||||
}
|
||||
|
||||
function handleValidateClick_Safe_Form() {
|
||||
function handleValidateClick() {
|
||||
formRef.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
window.$nMessage!.success('Valid');
|
||||
@@ -29,19 +30,6 @@ function handleValidateClick_Safe_Form() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleValidateClick_Normal() {
|
||||
formRefNormal.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
window.$nMessage!.success('Valid');
|
||||
} else {
|
||||
console.log(errors);
|
||||
window.$nMessage!.error('Invalid');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const formRefNormal = useTemplateRef('formRefNormal');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -60,7 +48,7 @@ const formRefNormal = useTemplateRef('formRefNormal');
|
||||
<n-form-item
|
||||
label="姓名"
|
||||
path="user.name"
|
||||
:rule="{ required: true, message: '请输入姓名', trigger: 'blur' }"
|
||||
:rule="{ required: true, message: '请输入姓名', trigger: ['input'] }"
|
||||
>
|
||||
<n-input v-model:value="formValue.user.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
@@ -68,45 +56,24 @@ const formRefNormal = useTemplateRef('formRefNormal');
|
||||
<n-form-item
|
||||
label="电话号码"
|
||||
path="phone"
|
||||
:rule="{ required: true, message: '请输入电话号码', trigger: ['input'] }"
|
||||
:rule="{ required: true, message: '请输入电话号码', trigger: ['blur'] }"
|
||||
>
|
||||
<n-input v-model:value="formValue.phone" placeholder="电话号码" />
|
||||
</n-form-item>
|
||||
|
||||
<SafeNFormItem #default="slotProps" path="phone">
|
||||
<SafeNFormItem #default="slotProps" path="user.name">
|
||||
<div class="border">
|
||||
<pre>{{ JSON.stringify({ slotProps }, null, 2) }}</pre>
|
||||
<div>v: {{ slotProps.value }}</div>
|
||||
</div>
|
||||
<!-- <NInput :value="value" placeholder="{props.placeholder}" /> -->
|
||||
<NInput :value="slotProps.value" placeholder="SafeNFormItem" />
|
||||
</SafeNFormItem>
|
||||
|
||||
<n-form-item>
|
||||
<n-button attr-type="button" @click="handleValidateClick_Safe_Form"> 验证 </n-button>
|
||||
<n-button attr-type="button" @click="handleValidateClick"> 验证 </n-button>
|
||||
</n-form-item>
|
||||
</SafeNForm>
|
||||
</n-card>
|
||||
|
||||
<n-card title="普通 Form" mt-4>
|
||||
<n-form ref="formRefNormal" inline :model="formValue">
|
||||
<n-form-item
|
||||
label="姓名"
|
||||
path="user.name"
|
||||
:rule="{ required: true, message: '请输入姓名', trigger: 'blur' }"
|
||||
>
|
||||
<n-input v-model:value="formValue.user.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="电话号码"
|
||||
path="phone"
|
||||
:rule="{ required: true, message: '请输入电话号码', trigger: ['input'] }"
|
||||
>
|
||||
<n-input v-model:value="formValue.phone" placeholder="电话号码" />
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button attr-type="button" @click="handleValidateClick_Normal"> 验证 </n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -16,6 +16,7 @@ export function useSafeNForm<T extends Record<string, any> = Record<string, unkn
|
||||
const formRef = ref<FormInst | null>(null);
|
||||
const formValue = ref<T>(structuredClone(toRaw(options.initialFormValue)) || ({} as T));
|
||||
|
||||
// 创建类型安全的 Form 组件
|
||||
interface SafeNFormProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
@@ -23,7 +24,6 @@ export function useSafeNForm<T extends Record<string, any> = Record<string, unkn
|
||||
default?: { count?: number };
|
||||
}>;
|
||||
|
||||
// 创建类型安全的 Form 组件
|
||||
const SafeNForm = defineComponent<SafeNFormProps, /* Emits */ [], /* EE */ never, SafeNFormSlots>(
|
||||
(props, ctx) => {
|
||||
return () => (
|
||||
@@ -48,31 +48,45 @@ export function useSafeNForm<T extends Record<string, any> = Record<string, unkn
|
||||
// <<<<<
|
||||
|
||||
// >>>>> 创建类型安全的 FormItem 组件
|
||||
interface SafeNFormItemProps {
|
||||
|
||||
type SafeNFormItemProps<P extends Paths<T> & string> = {
|
||||
label?: string;
|
||||
path: Paths<T> /* & string */;
|
||||
path: P;
|
||||
placeholder?: string;
|
||||
}
|
||||
type SafeNFormItemSlots = SlotsType<{
|
||||
default: {
|
||||
value: Get<T, string>;
|
||||
};
|
||||
|
||||
type SafeNFormItemSlotScope<P extends Paths<T> & string> = {
|
||||
value: Get<T, P>;
|
||||
};
|
||||
|
||||
type SafeNFormItemSlotsDefinition<P extends Paths<T> & string> = SlotsType<{
|
||||
default: SafeNFormItemSlotScope<P>;
|
||||
}>;
|
||||
|
||||
const SafeNFormItem = defineComponent<
|
||||
SafeNFormItemProps,
|
||||
type SafeNFormItemSlotFns<P extends Paths<T> & string> = {
|
||||
default?: (scope: SafeNFormItemSlotScope<P>) => any;
|
||||
};
|
||||
|
||||
type SafeNFormItemComponent = new <P extends Paths<T> & string>(
|
||||
props: SafeNFormItemProps<P>,
|
||||
) => {
|
||||
$props: SafeNFormItemProps<P>;
|
||||
$slots: SafeNFormItemSlotFns<P>;
|
||||
};
|
||||
|
||||
const SafeNFormItemImpl = defineComponent<
|
||||
SafeNFormItemProps<Paths<T> & string>,
|
||||
/* Emits */ [],
|
||||
/* EE */ never,
|
||||
SafeNFormItemSlots
|
||||
SafeNFormItemSlotsDefinition<Paths<T> & string>
|
||||
>(
|
||||
(props, ctx) => {
|
||||
return () => {
|
||||
const value = get(formValue.value, props.path) as Get<T, string>;
|
||||
const value = get(formValue.value, props.path) as Get<T, typeof props.path>;
|
||||
const slots = ctx.slots;
|
||||
return (
|
||||
<NFormItem>
|
||||
{ctx.slots.default?.({
|
||||
value,
|
||||
})}
|
||||
<NFormItem path={props.path} label={props.label}>
|
||||
{slots.default?.({ value })}
|
||||
</NFormItem>
|
||||
);
|
||||
};
|
||||
@@ -83,6 +97,7 @@ export function useSafeNForm<T extends Record<string, any> = Record<string, unkn
|
||||
props: ['label', 'path', 'placeholder'],
|
||||
},
|
||||
);
|
||||
const SafeNFormItem = SafeNFormItemImpl as unknown as SafeNFormItemComponent;
|
||||
// <<<<<
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user