You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Svelte 5中使用Superforms和shadcn-svelte的表单增强失效问题

Svelte 5 + Superforms 登录表单错误不显示问题解决

问题背景

用Svelte Kit搭配Svelte 5搭建新项目,基于shadcn-svelte和Superforms实现登录表单,代码如下:

<script lang="ts">
    import type {PageData} from "./$types";
    import {FormField, FormControl, FormLabel, FormButton, FormFieldErrors} from "$lib/components/ui/form";
    import {superForm} from "sveltekit-superforms";
    import {zodClient} from "sveltekit-superforms/adapters";
    import {formSchema} from "./schema.js";
    import {Input} from "$lib/components/ui/input";
    import {LoaderCircle} from 'lucide-svelte';
    import {Button} from "$lib/components/ui/button";

    let {data} = $props();

    let form = superForm(data.form, {
        validators: zodClient(formSchema)
    });

    const {form: formData, enhance, submitting} = form;
</script>

<form action="?/login" method="post" use:enhance>
        <FormField form={form} name="email">
            <FormControl>
                {#snippet children({props})}
                    <FormLabel>Email</FormLabel>
                    <Input {...props} bind:value={$formData.email} />
                {/snippet}
            </FormControl>
            <FormFieldErrors />
        </FormField>
        <FormField {form} name="password">
            <FormControl>
                {#snippet children({props})}
                    <FormLabel>Password</FormLabel>
                    <Input type="password" {...props} bind:value={$formData.password} />
                {/snippet}
            </FormControl>
            <FormFieldErrors />
        </FormField>
        <Button type="submit" disabled={$submitting}>
            {#if ($submitting)}
                <LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
            {/if}
            Sign in with email
        </Button>
</form>

遇到的问题:通过setError(form, 'email', "Message");返回错误时,开启渐进式增强(use:enhance)后页面不显示错误;禁用增强功能后显示正常。开发者工具显示请求成功且错误信息已返回,但页面未渲染;热重载应用时错误信息偶尔随机显示。

解决步骤

1. 移除手动的value绑定

Svelte 5中,Superforms的FormField组件已经通过props自动完成值的绑定,手动添加bind:value={$formData.email}会破坏响应式同步,导致错误状态无法更新到DOM。

修改Input部分代码:

<!-- 原代码 -->
<Input {...props} bind:value={$formData.email} />
<!-- 修改后 -->
<Input {...props} />

密码字段同理,去掉bind:value={$formData.password}。

2. 适配Svelte 5的组件传参方式

Svelte 5已不推荐使用$props(),改用export let声明组件props,确保数据传递的响应式正确:

<!-- 原代码 -->
let {data} = $props();
<!-- 修改后 -->
export let data: PageData;

3. 确保Superforms版本兼容Svelte 5

检查package.json中sveltekit-superforms版本需>=2.10.0,该版本开始全面支持Svelte 5的Runes语法和响应式系统。如果版本过低,执行升级命令:

npm install sveltekit-superforms@latest

4. 验证服务端Action的错误返回逻辑

确保服务端的login action中,setError的使用符合Superforms要求,示例:

import { setError, superValidate, fail } from 'sveltekit-superforms/server';
import { formSchema } from './schema.js';

export const actions = {
  login: async ({ request }) => {
    const form = await superValidate(request, formSchema);
    
    // 模拟验证失败场景
    if (!form.data.email.includes('@')) {
      setError(form, 'email', '请输入有效的邮箱地址');
      return fail(400, { form });
    }
    
    // 其他业务逻辑...
    return { form };
  }
};

修改后重新测试,渐进式增强模式下错误信息应该能正常渲染。

内容的提问来源于stack exchange,提问作者DevOskar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:55:58