feat: 更新 PSelect 组件,支持异步选项加载并优化 blur 事件处理
This commit is contained in:
@ -6,6 +6,9 @@
|
|||||||
- [sections](https://formkit.com/inputs/text#sections)
|
- [sections](https://formkit.com/inputs/text#sections)
|
||||||
- [sections](https://formkit.com/essentials/inputs#sections)
|
- [sections](https://formkit.com/essentials/inputs#sections)
|
||||||
- [useformkitcontext](https://formkit.com/inputs/form#useformkitcontext)
|
- [useformkitcontext](https://formkit.com/inputs/form#useformkitcontext)
|
||||||
|
- [debouncing](https://formkit.com/essentials/inputs#debouncing)
|
||||||
|
|
||||||
|
延迟 prop 的默认值是 20 毫秒。然而,group 和 list 输入默认使用 0 毫秒,以防止防抖延迟在每个深度级别“累积”。
|
||||||
|
|
||||||
## Custom Input
|
## Custom Input
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import type { FormKitFrameworkContext, FormKitTypeDefinition } from '@formkit/co
|
|||||||
import type { FormKitInputs } from '@formkit/inputs';
|
import type { FormKitInputs } from '@formkit/inputs';
|
||||||
import { createSection, label, outer } from '@formkit/inputs';
|
import { createSection, label, outer } from '@formkit/inputs';
|
||||||
import PrimevueSelect, { type SelectEmitsOptions } from 'primevue/select';
|
import PrimevueSelect, { type SelectEmitsOptions } from 'primevue/select';
|
||||||
import { defineComponent, markRaw } from 'vue';
|
import { defineComponent, markRaw, ref } from 'vue';
|
||||||
import { floatLabel } from '../sections/floatLabel';
|
import { floatLabel } from '../sections/floatLabel';
|
||||||
import { messages } from '../sections/messages';
|
import { messages } from '../sections/messages';
|
||||||
|
|
||||||
@ -21,14 +21,23 @@ const PSelectComp = defineComponent(
|
|||||||
formkitContext.node.input(value);
|
formkitContext.node.input(value);
|
||||||
},
|
},
|
||||||
'onBlur': async e => {
|
'onBlur': async e => {
|
||||||
setTimeout(() => formkitContext.handlers.blur.call(undefined, e as never), 20);
|
setTimeout(
|
||||||
|
() => formkitContext.handlers.blur.call(undefined, e as never),
|
||||||
|
166, // 因为会触发两次。所以让blur事件延迟一点,可以考虑优化。
|
||||||
|
);
|
||||||
},
|
},
|
||||||
/* https://formkit.com/essentials/inputs#debouncing
|
|
||||||
* The default debounce delay is 20 milliseconds and can be adjusted with the delay prop or config option.
|
|
||||||
* 延迟 prop 的默认值是 20 毫秒。然而,group 和 list 输入默认使用 0 毫秒,以防止防抖延迟在每个深度级别“累积”。
|
|
||||||
* 不过好像不是这个造成的`blur`比`change`先触发。
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
const poptions = ref();
|
||||||
|
const loading = ref(true);
|
||||||
|
if (formkitContext.options instanceof Promise) {
|
||||||
|
formkitContext.options.then((res: any) => {
|
||||||
|
poptions.value = res;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
poptions.value = formkitContext.options;
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
return (
|
return (
|
||||||
@ -37,8 +46,11 @@ const PSelectComp = defineComponent(
|
|||||||
fluid
|
fluid
|
||||||
invalid={formkitContext.state.invalid}
|
invalid={formkitContext.state.invalid}
|
||||||
disabled={!!formkitContext.disabled}
|
disabled={!!formkitContext.disabled}
|
||||||
options={formkitContext.options}
|
loading={loading.value}
|
||||||
|
options={poptions.value}
|
||||||
modelValue={formkitContext._value}
|
modelValue={formkitContext._value}
|
||||||
|
optionLabel={formkitContext.optionLabel as never}
|
||||||
|
optionValue={formkitContext.optionValue as never}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -69,16 +81,19 @@ export const PSelect: FormKitTypeDefinition = {
|
|||||||
),
|
),
|
||||||
messages(),
|
messages(),
|
||||||
),
|
),
|
||||||
props: ['options'],
|
props: ['options', 'optionLabel', 'optionValue'],
|
||||||
// schemaMemoKey: 'nnvujvlf2xr', // Math.random().toString(36).substring(2, 15)
|
// schemaMemoKey: 'nnvujvlf2xr', // Math.random().toString(36).substring(2, 15)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type OptionsItem = Record<string, any>;
|
||||||
|
type OptionsType = Array<OptionsItem>;
|
||||||
|
|
||||||
declare module '@formkit/inputs' {
|
declare module '@formkit/inputs' {
|
||||||
// https://formkit.com/essentials/custom-inputs#typescript-support
|
// https://formkit.com/essentials/custom-inputs#typescript-support
|
||||||
interface FormKitInputProps<Props extends FormKitInputs<Props>> {
|
interface FormKitInputProps<Props extends FormKitInputs<Props>> {
|
||||||
PSelect: {
|
PSelect: {
|
||||||
type: 'PSelect';
|
type: 'PSelect';
|
||||||
options: any;
|
options: OptionsType | Promise<OptionsType>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,19 @@ async function submit(formData: Record<string, any>, formNode: FormKitNode) {
|
|||||||
timer: 1500
|
timer: 1500
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const K_OPTIONS = [
|
||||||
|
{ label: 'Option 1', value: 'Value 1' },
|
||||||
|
{ label: 'Option 2', value: 'Value 2' },
|
||||||
|
{ label: 'Option 3', value: 'Value 3' },
|
||||||
|
];
|
||||||
|
const promiseOptions = () => {
|
||||||
|
return new Promise<typeof K_OPTIONS>(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(K_OPTIONS);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -71,13 +84,20 @@ async function submit(formData: Record<string, any>, formNode: FormKitNode) {
|
|||||||
name="PSelect"
|
name="PSelect"
|
||||||
label="选择框"
|
label="选择框"
|
||||||
validation="required"
|
validation="required"
|
||||||
:options="[
|
:options="K_OPTIONS"
|
||||||
'Option 1',
|
optionLabel="label"
|
||||||
'Option 2',
|
optionValue="value"
|
||||||
'Option 3',
|
|
||||||
]"
|
|
||||||
valuee="Option 2"
|
|
||||||
/>
|
/>
|
||||||
|
<FormKit
|
||||||
|
type="PSelect"
|
||||||
|
name="PSelect"
|
||||||
|
label="选择框"
|
||||||
|
validation="required"
|
||||||
|
:options="promiseOptions()"
|
||||||
|
optionLabel="label"
|
||||||
|
optionValue="value"
|
||||||
|
/>
|
||||||
|
<div class="flex gap-4">
|
||||||
<FormKit
|
<FormKit
|
||||||
v-if="!value?.PInputPassword"
|
v-if="!value?.PInputPassword"
|
||||||
:type="text"
|
:type="text"
|
||||||
@ -112,6 +132,7 @@ async function submit(formData: Record<string, any>, formNode: FormKitNode) {
|
|||||||
>
|
>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
label="Button"
|
label="Button"
|
||||||
|
Reference in New Issue
Block a user