7
4

【v0】UIを生成AIで簡単に作る方法!

Last updated at Posted at 2024-09-14

はじめに

本記事はANGEL Calendar、15日目の記事となります!
記事一覧は↓のOrganizationアカウントの一覧をチェックしてみてください!

本記事の内容

「v0」というユーザーインターフェース(UI)を簡単に作成できるツールの概要、使い方を紹介します!

ハッカソンや個人開発で簡単にUIを作成したいといった方や、React初学者にも役立つ内容だと思いますので、ぜひ目を通していただければと思います。

v0とは?

Next.jsの開発で知られるVercel Inc.によって開発された、ChatGPTのようなチャット形式でやり取りを行い、UIを生成できるツールです。

要件を入力することで、shadcn/uiTailwind CSSを用いたReactコードが生成され、コピー&ペーストでNext.jsやReactに組み込むことができます。

v0の使い方

  1. ↑のURLにアクセスする。
  2. ログイン(アカウント登録)する。
  3. 要件を入力する。
  4. UIが生成される。
    (5. 追加の要件を伝える。)
  5. ReactやNext.jsに組み込んでみる。

利用上限はありますが、無料で利用できます。(200 credits/month)
UIの初期生成に30クレジット、追加修正に10クレジット消費されます。

※2024.9.15時点

使用例(ToDoアプリのUI作成)

では、実際の使ってみます。

まずは、右上のSign Inからログインをして...
CleanShot 2024-09-14 at 16.56.09@2x.png

要件を入力します。
今回はToDoアプリを作ってもらおうと思います。
CleanShot 2024-09-14 at 16.57.11@2x.png

入力した要件からコードが生成され、プレビューが表示されます。(数秒で生成されます!)
※ToDoリストの項目は後から追加しています。
CleanShot 2024-09-14 at 17.03.12@2x.png

生成されたコードはこちら
red-todo-app.tsx
"use client"

import { useState } from "react"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Trash2 } from "lucide-react"

type Todo = {
  id: number
  text: string
  completed: boolean
}

export default function Component() {
  const [todos, setTodos] = useState<Todo[]>([])
  const [newTodo, setNewTodo] = useState("")

  const addTodo = () => {
    if (newTodo.trim() !== "") {
      setTodos([...todos, { id: Date.now(), text: newTodo, completed: false }])
      setNewTodo("")
    }
  }

  const toggleTodo = (id: number) => {
    setTodos(todos.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ))
  }

  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id))
  }

  return (
    <div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-lg">
      <h1 className="text-3xl font-bold mb-6 text-red-600">TODOアプリ</h1>
      <div className="flex mb-4">
        <Input
          type="text"
          value={newTodo}
          onChange={(e) => setNewTodo(e.target.value)}
          placeholder="新しいタスクを入力"
          className="flex-grow mr-2"
        />
        <Button onClick={addTodo} className="bg-red-600 hover:bg-red-700">
          追加
        </Button>
      </div>
      <ul className="space-y-2">
        {todos.map(todo => (
          <li key={todo.id} className="flex items-center justify-between bg-gray-100 p-3 rounded">
            <div className="flex items-center">
              <Checkbox
                checked={todo.completed}
                onCheckedChange={() => toggleTodo(todo.id)}
                className="mr-2 border-red-600 text-red-600"
              />
              <span className={todo.completed ? "line-through text-gray-500" : ""}>
                {todo.text}
              </span>
            </div>
            <Button
              variant="ghost"
              size="icon"
              onClick={() => deleteTodo(todo.id)}
              className="text-red-600 hover:text-red-700"
            >
              <Trash2 className="h-4 w-4" />
            </Button>
          </li>
        ))}
      </ul>
    </div>
  )
}

 

このままでも十分ですが、試しにタイトル部分の下線の追加と、追加ボタンの「追加」を「+」に変えてみました。
ちゃんと実装できていますね!

CleanShot 2024-09-14 at 17.10.51@2x.png

改良されたコードはこちら
red-todo-app.tsx
"use client"

import { useState } from "react"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Trash2, Plus } from "lucide-react"

type Todo = {
  id: number
  text: string
  completed: boolean
}

export default function Component() {
  const [todos, setTodos] = useState<Todo[]>([])
  const [newTodo, setNewTodo] = useState("")

  const addTodo = () => {
    if (newTodo.trim() !== "") {
      setTodos([...todos, { id: Date.now(), text: newTodo, completed: false }])
      setNewTodo("")
    }
  }

  const toggleTodo = (id: number) => {
    setTodos(todos.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ))
  }

  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id))
  }

  return (
    <div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-lg">
      <h1 className="text-3xl font-bold mb-2 text-red-600 pb-2 border-b-2 border-red-600">TODOアプリ</h1>
      <div className="flex mb-4 mt-6">
        <Input
          type="text"
          value={newTodo}
          onChange={(e) => setNewTodo(e.target.value)}
          placeholder="新しいタスクを入力"
          className="flex-grow mr-2"
        />
        <Button onClick={addTodo} className="bg-red-600 hover:bg-red-700 px-3">
          <Plus className="h-5 w-5" />
          <span className="sr-only">追加</span>
        </Button>
      </div>
      <ul className="space-y-2">
        {todos.map(todo => (
          <li key={todo.id} className="flex items-center justify-between bg-gray-100 p-3 rounded">
            <div className="flex items-center">
              <Checkbox
                checked={todo.completed}
                onCheckedChange={() => toggleTodo(todo.id)}
                className="mr-2 border-red-600 text-red-600"
              />
              <span className={todo.completed ? "line-through text-gray-500" : ""}>
                {todo.text}
              </span>
            </div>
            <Button
              variant="ghost"
              size="icon"
              onClick={() => deleteTodo(todo.id)}
              className="text-red-600 hover:text-red-700"
            >
              <Trash2 className="h-4 w-4" />
            </Button>
          </li>
        ))}
      </ul>
    </div>
  )
}

価格や商用利用については、よくある質問に記述されています。

おわりに

実際に試してみると分かるのですが、本当に一瞬でUIが作成できます!
現時点でもかなり便利ですが、まだPublic Beta版なので、今後の進化が楽しみです。

ぜひ一度、触っていただき、v0の凄さを体感していただければと思います!

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4