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

在SvelteKit中实现表单Action触发的加载Spinner

问题

我有一个包含邮箱、密码和确认密码的简单表单,使用SvelteKit的Action处理提交。基于PocketBase数据库,我希望在以下两个阶段触发加载Spinner:1. 检查数据库中是否已存在该用户;2. 若用户不存在则执行注册流程。我尝试在Action中设置isLoading布尔值标记加载状态,但无法在客户端获取该状态的初始及更新值;曾尝试使用Store,却发现Store无法在服务端与客户端之间共享状态。请问有什么可行的替代方案?

以下是我的Action代码:

import { superValidate } from 'sveltekit-superforms/server';
import { redirect } from '@sveltejs/kit';
import { fail } from '@sveltejs/kit';

import { loginSchema } from '$lib/schema/zodschema';
import { ClientResponseError } from 'pocketbase';

export const load = async () => {
    const form = await superValidate(loginSchema);
    return { form };
};

export const actions = {
    default: async ({ locals, request }) => {
        const form = await superValidate(request, loginSchema);


        try {

            const { email } = form.data
            const records = await locals.pb.collection('test').getFullList();
            const userRecords = records.filter(value => value.email === form.data.email);

            if (userRecords.length > 0) {

                const existingUser = userRecords[0]

                if (existingUser && existingUser.verified) {
                    return {

                        accountCreated: false,
                        message: 'The user records exists. Proceed to login instead',
                        isVerified: true,

                    }
                } else {


                    return {

                        accountCreated: false,
                        message: 'The user record exists. You have to verify to access',
                        isVerified: false,


                    }
                }
            } else {
                await locals.pb.collection('test').create(form.data);



                return {

                    accountCreated: true,
                    message: 'The user record is successfully created',
                    isVerified: false,
                }
            }



        } catch (error) {
            // Handle the error

            if (error instanceof ClientResponseError) {
                return {
                    error: error.message,
                    isLoading: false
                }
            }
        }
    }
};

我曾尝试设置let isLoading = true并在不同阶段设为false,但核心问题是如何在客户端获取该状态。

解决方案

方法一:用SvelteKit内置的use:enhance跟踪提交状态

不需要在服务端传递isLoading,直接在客户端通过表单钩子监听提交流程:

<script>
    import { enhance } from '$app/forms';
    let isLoading = false;
</script>

<form method="POST" use:enhance={({ cancel }) => {
    isLoading = true; // 提交开始时激活加载状态

    return async ({ update }) => {
        await update(); // 等待服务端Action处理完成
        isLoading = false; // 处理结束后关闭加载
    };
}}>
    <!-- 邮箱、密码等表单输入框 -->
    
    {#if isLoading}
        <div>加载中...</div>
    {/if}
    <button type="submit" disabled={isLoading}>提交</button>
</form>

这个逻辑会覆盖你需要的两个阶段——检查用户存在性、注册流程,因为这两个步骤都属于服务端Action的处理周期,提交开始就显示加载,结束后自动隐藏。

方法二:利用Superforms的内置loading状态

既然你已经在用superValidate,Superforms本身提供了现成的加载状态,不用额外维护:

<script>
    import { superForm } from 'sveltekit-superforms/client';
    export let data;
    
    const { form, enhance } = superForm(data.form);
</script>

<form method="POST" use:enhance>
    <!-- 表单元素 -->
    
    {#if form.loading}
        <div>加载中...</div>
    {/if}
    <button type="submit" disabled={form.loading}>提交</button>
</form>

form.loading会在表单提交到服务端的过程中自动变为true,处理完成后恢复false,完全匹配你的需求,而且不需要修改服务端Action代码。

额外优化:提升服务端查询效率

你当前用getFullList()全量拉取数据再过滤的方式,用户量上来后会很慢,建议改用PocketBase的精准查询:

// 替换原Action中的用户查询逻辑
try {
    // 直接查询匹配邮箱的用户
    const existingUser = await locals.pb.collection('test').getFirstListItem(`email = "${form.data.email}"`);
    
    // 原有的已存在用户判断逻辑
    if (existingUser.verified) {
        return {
            accountCreated: false,
            message: 'The user records exists. Proceed to login instead',
            isVerified: true
        };
    } else {
        return {
            accountCreated: false,
            message: 'The user record exists. You have to verify to access',
            isVerified: false
        };
    }
} catch (error) {
    if (error instanceof ClientResponseError && error.status === 404) {
        // 404表示用户不存在,执行注册
        await locals.pb.collection('test').create(form.data);
        return {
            accountCreated: true,
            message: 'The user record is successfully created',
            isVerified: false
        };
    }
    // 处理其他错误
    return { error: error.message };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:05:40