如何从Svelte表单组件获取值?服务器端收不到note数据
问题:shadcn-svelte表单组件服务器端无法获取Markdown编辑器输入值
我用shadcn-svelte的表单组件开发,想在服务器端拿到用户输入的note字段值,但按照官方示例操作后,+page.server.ts里用console.log打印时,note始终是空值。
组件代码(+page.svelte)
<script lang="ts"> import { Carta, MarkdownEditor } from 'carta-md'; import { code } from '@cartamd/plugin-code'; import 'carta-md/default.css'; import { browser } from '$app/environment'; import '$lib/styles/github.scss'; import { formSchema } from './schema'; import { superForm } from 'sveltekit-superforms'; import SuperDebug from 'sveltekit-superforms'; import { zodClient } from 'sveltekit-superforms/adapters'; import * as Form from '$lib/components/ui/form/index'; import type { PageData } from '../$types'; export let data: PageData; const form = superForm(data.form, { validators: zodClient(formSchema) }); const { form: formData, enhance } = form; // TODO: 编辑器切换浅色模式时背景色不变 const carta = new Carta({ sanitizer: false, extensions: [code()] }); </script> <div class="flex w-3/4 flex-col"> <form method="POST" use:enhance> <Form.Field {form} name="note"> <Form.Control> <div class="flex flex-col justify-end space-y-4"> <MarkdownEditor bind:value={$formData.note} {carta} mode="tabs" theme="github" placeholder="Enter your note" /> </div> </Form.Control> <Form.FieldErrors /> </Form.Field> <Form.Button variant="default" type="submit">Save</Form.Button> {#if browser} <SuperDebug data={$formData} /> {/if} </form> </div>
+page.server.ts代码
import type { Actions } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; import { superValidate } from 'sveltekit-superforms'; import { formSchema } from './schema'; import { zod } from 'sveltekit-superforms/adapters'; export const load: PageServerLoad = async () => { return { form: await superValidate(zod(formSchema)) }; }; export const actions: Actions = { default: async ({ request }) => { const form = await superValidate(request, zod(formSchema)); console.log(form); } };
Zod Schema代码(schema.ts)
import { z } from 'zod'; export const formSchema = z.object({ note: z.string().min(2, 'Too short! The note must have atleast 20 characters') }); export type FormSchema = typeof formSchema;
解决方法
核心原因
第三方MarkdownEditor不是原生表单控件(如input/textarea),shadcn-svelte的Form组件依赖原生表单字段的name属性收集提交数据,导致编辑器的值无法被自动传递到服务器。
修复步骤
- 添加隐藏的原生textarea
在Form.Control内部、MarkdownEditor下方添加一个隐藏的textarea,绑定到$formData.note,让表单提交时能带上这个值:
<Form.Control> <div class="flex flex-col justify-end space-y-4"> <MarkdownEditor bind:value={$formData.note} {carta} mode="tabs" theme="github" placeholder="Enter your note" /> <!-- 新增隐藏textarea,用于表单提交传递值 --> <textarea name="note" bind:value={$formData.note} class="hidden" /> </div> </Form.Control>
- 修正Zod Schema的逻辑错误
你的schema里min(2)但提示文字要求至少20字符,逻辑不一致,修正为:
export const formSchema = z.object({ note: z.string().min(20, 'Too short! The note must have at least 20 characters') });
- 优化服务器端代码(可选)
添加表单验证失败的返回逻辑,方便客户端展示错误:
import { fail } from '@sveltejs/kit'; export const actions: Actions = { default: async ({ request }) => { const form = await superValidate(request, zod(formSchema)); console.log(form.data.note); // 直接打印note值 if (!form.valid) { return fail(400, { form }); } // 这里处理你的业务逻辑(比如保存到数据库) return { form }; } };
这样修改后,服务器端就能正确获取到Markdown编辑器的输入值了。
内容的提问来源于stack exchange,提问作者monte
相关产品推荐
相关产品推荐

