Closed1

Svelte form検証で。zod 使う例

knaka Tech-Blogknaka Tech-Blog

概要

Svelteで zod使うメモになります。

[ 公開: 2024/04/20 ]


環境

  • Svelte
  • zod
  • vercel

作成したコード

https://github.com/kuc-arc-f/express_33svelte/tree/main/sample/zod_test


  • client/Zod/Validate.ts
  • z.object: 検証の定義、型の指定など
  • FormData.parse で、検証の実行みたいでした。
Validate.ts
import { z } from 'zod';
//
const FormData = z.object({
    title: z
    .string()
    .min(2, { message: '2文字以上入力してください。' }),
    content: z
    .string()
    .min(2, { message: '2文字以上入力してください。' }),
});
//
const Validate = {
  /**
   * 
   * @param
   *
   * @return
   */
  formValidate: function(input){
    let errors = {};
    try {
      FormData.parse(input);
      return errors;
    } catch (e) {
      console.error(e.flatten().fieldErrors);
      return e.flatten().fieldErrors;
    }
  },
}
export default Validate;


  • client/Zod.svelte: .svelteから、検証する
  • #if errors?.title などの分岐で、エラー文字表示する
<script lang="ts">
import type { ComponentEvents } from 'svelte';
import type { SvelteHTMLElements  } from 'svelte/elements';
type InputOnChangeEvent = SvelteHTMLElements['input']['on:change']

import HttpCommon from './lib/HttpCommon';
import CrudIndex from './Zod/CrudIndex';
import Crud from './Zod/Crud';
import Validate from './Zod/Validate';

export let errors = {};
//
const testProc = async function(){
  const input = Crud.getInputValues();
  errors = Validate.formValidate(input);
console.log(errors);
  if (Object.keys(errors).length > 0) {
    alert("Error!");
  }
}
</script>

<!-- -->
<div class="container mx-auto my-2 px-8 bg-white">
  <hr class="my-2" />
  <h1 class="text-4xl font-bold">Zod test!!</h1>
  <hr class="my-2" />
  <label>Title:
    <input type="text" id="title" 
    class="border border-gray-400 rounded-md px-3 py-2 w-full focus:outline-none focus:border-blue-500"
    />    
  </label>
  {#if errors?.title}
    <em class="error_message">{errors?.title}</em>
  {/if}
  <hr class="my-2" />
  <label>Content:
    <input type="text" id="content" 
    class="border border-gray-400 rounded-md px-3 py-2 w-full focus:outline-none focus:border-blue-500"
    />    
  </label>
  {#if errors?.content}
    <em class="error_message">{errors?.content}</em>
  {/if}
  <hr class="my-2" />
  <button on:click={() => testProc()} class="btn-purple">Test
  </button>
</div>

<style>
</style>

<!--
-->


このスクラップは13日前にクローズされました