feat: 更新 PSelect 组件,添加 value 插槽支持,优化选项加载和输入交互体验
This commit is contained in:
@ -4,7 +4,7 @@ import AllCustom from './all-custom/all-custom.vue';
|
|||||||
import TutorialForm from './tutorial-form/index.vue';
|
import TutorialForm from './tutorial-form/index.vue';
|
||||||
import ZodForm from './zod-form/index.vue';
|
import ZodForm from './zod-form/index.vue';
|
||||||
|
|
||||||
const selectedCity = ref();
|
const selectedCity = ref('NY');
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const cities = ref([
|
const cities = ref([
|
||||||
{ name: 'New York', code: 'NY' },
|
{ name: 'New York', code: 'NY' },
|
||||||
@ -53,6 +53,12 @@ const handleE = (eventName: string) => {
|
|||||||
@change="(e) => handleE('change')(e)"
|
@change="(e) => handleE('change')(e)"
|
||||||
@blur="(e) => handleE('blur')(e)"
|
@blur="(e) => handleE('blur')(e)"
|
||||||
></Select>
|
></Select>
|
||||||
|
<Select
|
||||||
|
:options="cities"
|
||||||
|
class="w-full md:w-56"
|
||||||
|
>
|
||||||
|
<template #value="slotProps">{{ slotProps.value }}</template>
|
||||||
|
</Select>
|
||||||
<Button
|
<Button
|
||||||
id="load-selected-city"
|
id="load-selected-city"
|
||||||
label="Load Selected City"
|
label="Load Selected City"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { FormKitFrameworkContext, FormKitTypeDefinition } from '@formkit/core';
|
import type { FormKitFrameworkContext, FormKitTypeDefinition } from '@formkit/core';
|
||||||
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, type SelectSlots } from 'primevue/select';
|
||||||
import { defineComponent, markRaw, ref } from 'vue';
|
import { computed, 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';
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ type PrimevueSelectListeners = {
|
|||||||
const PSelectComp = defineComponent(
|
const PSelectComp = defineComponent(
|
||||||
(vueProps: { context: FormKitFrameworkContext }) => {
|
(vueProps: { context: FormKitFrameworkContext }) => {
|
||||||
const formkitContext = vueProps.context;
|
const formkitContext = vueProps.context;
|
||||||
|
const primevueSelectInstance = ref<Record<string, any> | undefined>();
|
||||||
const listeners: PrimevueSelectListeners = {
|
const listeners: PrimevueSelectListeners = {
|
||||||
'onUpdate:modelValue': (value: any) => {
|
'onUpdate:modelValue': (value: any) => {
|
||||||
formkitContext.node.input(value);
|
formkitContext.node.input(value);
|
||||||
@ -56,12 +57,23 @@ const PSelectComp = defineComponent(
|
|||||||
|
|
||||||
loadOptions(); // 立即加载options
|
loadOptions(); // 立即加载options
|
||||||
|
|
||||||
|
const valueSlot = computed(() => {
|
||||||
|
if (primevueSelectInstance.value?.label === 'p-emptylabel' && !!formkitContext._value) {
|
||||||
|
return (slotProps => {
|
||||||
|
return slotProps.value as never;
|
||||||
|
}) satisfies SelectSlots['value'];
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
return (
|
return (
|
||||||
<PrimevueSelect
|
<PrimevueSelect
|
||||||
|
ref={primevueSelectInstance}
|
||||||
labelId={formkitContext.id}
|
labelId={formkitContext.id}
|
||||||
fluid
|
fluid
|
||||||
invalid={formkitContext.state.invalid}
|
invalid={formkitContext.state.invalid || valueSlot.value !== undefined}
|
||||||
disabled={!!formkitContext.disabled}
|
disabled={!!formkitContext.disabled}
|
||||||
loading={loading.value}
|
loading={loading.value}
|
||||||
options={poptions.value}
|
options={poptions.value}
|
||||||
@ -69,7 +81,11 @@ const PSelectComp = defineComponent(
|
|||||||
optionLabel={formkitContext.optionLabel as never}
|
optionLabel={formkitContext.optionLabel as never}
|
||||||
optionValue={formkitContext.optionValue as never}
|
optionValue={formkitContext.optionValue as never}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
/>
|
>
|
||||||
|
{{
|
||||||
|
value: valueSlot.value,
|
||||||
|
}}
|
||||||
|
</PrimevueSelect>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -87,6 +87,7 @@ const promiseOptions = new Promise<typeof K_OPTIONS>(resolve => {
|
|||||||
:options="K_OPTIONS"
|
:options="K_OPTIONS"
|
||||||
optionLabel="label"
|
optionLabel="label"
|
||||||
optionValue="value"
|
optionValue="value"
|
||||||
|
value="数据的值不在options里"
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="PSelect"
|
type="PSelect"
|
||||||
|
Reference in New Issue
Block a user