要点
- 使用
:model
而不是v-model
关联formState
- 使用
emits('update:modelValue', value)
向上层传递formState变化而不是直接修改p.modelValue的值
- 在
@finish
事件中触发emits('submit')
向上层传递提交事件,以便程序调用后端服务
<script lang="ts" setup>
import { useReactive } from '../../../../hooks/useReactive'
import type { Question } from '../util'
import { QuestionType } from '../util'
const p = defineProps<{
questions: Question[]
modelValue: Record<string, number>
readOnly: boolean
}>()
const emits = defineEmits<{
(e: 'update:modelValue', v: Record<string, number>): void
(e: 'submit'): void
}>()
const s = useReactive(() => new class {
get formState() {
return p.modelValue
}
set formState(value) {
emits('update:modelValue', value)
}
onSubmit() {
emits('update:modelValue', s.formState)
emits('submit')
}
onFailed(e: any) {
console.debug('onFailed', e)
}
}())
function label(originLabel: string, index: number) {
return `${index + 1}. ${originLabel}`
}
</script>
<template>
<AForm :model="s.formState" @finish="s.onSubmit" @failed="s.onFailed">
<AFormItem v-for="(it, index) in p.questions" :key="it.fieldName" :name="it.fieldName" :label="label(it.label, index)">
<ARadioGroup
v-if="it.type === QuestionType.RADIO"
v-model:value="s.formState[it.fieldName]"
:disabled="!!p.readOnly" :options="it.options"
/>
<AInput
v-else-if="it.type === QuestionType.INPUT_NUMBER"
v-model:value="s.formState[it.fieldName]"
type="number"
:disabled="p.readOnly"
:max="it.max" :min="it.min"
:default-value="it.defaultValue"
/>
</AFormItem>
<AButton block type="primary" html-type="submit">
提交
</AButton>
</AForm>
</template>
<style scoped>
</style>
网友评论