使用 Zod 进行架构验证 - Vue 3

问题描述 投票:0回答:1

我在 Nuxt 3 项目中使用 Shadcn-ui (https://www.shadcn-vue.com/docs/components/combobox#combobox) 中的组合框。我无法使用 zod 验证我的组合框。当我选择一个元素并提交表单时,我总是收到错误消息“需要帐户”。 无论我选择什么,验证都不会通过。有人可以帮我找到问题吗?

我的代码:

<script setup lang="ts">

const accounts = [
    { value: 'nuxt.js', label: 'Nuxt.js' },
    { value: 'remix', label: 'Remix' },
    { value: 'astro', label: 'Astro' },
]
const open = ref(false)
const value = ref('')

const formSchema = toTypedSchema(z.object({
    accountSelected: z.string({
        required_error: "Account is required"
    }),
    setupName: z.string({
        required_error: "Setup is required"
    })
}))

const form = useForm({
    validationSchema: formSchema,
})

const submitForm = form.handleSubmit((values) => {
    console.log("form submitted");
})
</script>

<template>

    <form @submit="submitForm">
        <FormField v-slot="{ componentField }" name="accountSelected">
            <FormItem class="flex flex-col">
                <FormLabel>Select account</FormLabel>
                <FormControl>
                    <Popover v-model:open="open">
                        <PopoverTrigger as-child>
                            <Button variant="outline" role="combobox" :aria-expanded="open">
                                {{ value
                                    ? accounts.find((account) => account.value === value)?.label
                                    : "Select account..." }}
                                <ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
                            </Button>
                        </PopoverTrigger>
                        <PopoverContent>
                            <Command>
                                <CommandInput placeholder="Search account..." />
                                <CommandEmpty>No account found.</CommandEmpty>
                                <CommandList>
                                    <CommandGroup>
                                        <CommandItem v-bind="componentField" v-for="account in accounts"
                                            :key="account.value" :value="account.value" @select="(ev) => {
                                                if (typeof ev.detail.value === 'string') {
                                                    value = ev.detail.value
                                                }
                                                open = false
                                            }">
                                            {{ account.label }}
                                            <Check :class="cn(
                                                'ml-auto h-4 w-4',
                                                value === account.value ? 'opacity-100' : 'opacity-0',
                                            )" />
                                        </CommandItem>
                                    </CommandGroup>
                                </CommandList>
                            </Command>
                        </PopoverContent>
                    </Popover>
                </FormControl>
                <FormMessage />
            </FormItem>
        </FormField>
        <FormField v-slot="{ componentField }" name="setupName">
            <FormItem>
                <FormLabel>Name</FormLabel>
                <FormControl>
                    <Input type="text" v-bind="componentField" />
                </FormControl>
                <FormMessage />
            </FormItem>
        </FormField>
        <Button type="submit" class="flex justify-center items-center">
            Send
        </Button>
    </form>

</template>
vuejs3 nuxtjs3 shadcnui
1个回答
0
投票

尝试手动设置值,如下所示:

@select="(ev) => {
  if (typeof ev.detail.value === 'string') {
    value = ev.detail.value
    form.setFieldValue('accountSelected', ev.detail.value)
  }
  open = false
}"
© www.soinside.com 2019 - 2024. All rights reserved.