6
社区成员
发帖
与我相关
我的任务
分享在今天的文章中,我们将使用 Next.js 和 GraphQL Yoga 创建一个完整的堆栈应用程序。
动图
在开始本文之前,建议您了解 React、Next.js 和 GraphQL。
要在 Remix 中初始化项目,我们执行以下命令:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npx create-next-app@latest my-app
</code></span></span>
使用的设置包括 TypeScript、ESLint、Tailwind CSS,我们正在使用app路由器。
我们使用以下命令启动开发服务器:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npm run dev
</code></span></span>
除了基本配置之外,我们还使用daisyUI库来使用预先样式化的组件。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npm <span style="color:var(--syntax-text-color)">install </span>daisyui
</code></span></span>
然后我们将库添加到文件中的插件列表中tailwind.config.js,我们还可以在其中定义要使用的主题,如下所示:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">module</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">exports</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-comment-color)">// ...</span>
<span style="color:var(--syntax-name-color)">plugins</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-name-color)">require</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">daisyui</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)],</span>
<span style="color:var(--syntax-name-color)">daisyui</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">themes</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">winter</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">],</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">};</span>
</code></span></span>
应用程序设置准备就绪后,我们可以继续下一步。
首先,我们需要配置与数据库的连接,以便我们可以将数据保存在应用程序中。为了促进整个过程,我们将使用 ORM,在本文中我决定选择Drizzle ORM。对于数据库,我决定使用 SQLite,因为它是最容易访问的。
我们首先安装依赖项:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npm <span style="color:var(--syntax-text-color)">install </span>drizzle-orm better-sqlite3
npm <span style="color:var(--syntax-text-color)">install</span> <span style="color:var(--syntax-error-color)">-D</span> drizzle-kit @types/better-sqlite3
</code></span></span>
然后在该server/文件夹中,我们将创建一个名为 的文件夹db/,其中将包含连接和数据库架构。
从配置开始,让我们server/db/config.ts使用以下内容创建文件:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">drizzle</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">drizzle-orm/better-sqlite3</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">migrate</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">drizzle-orm/better-sqlite3/migrator</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">Database</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">better-sqlite3</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">sqlite</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">new</span> <span style="color:var(--syntax-name-color)">Database</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">sqlite.db</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">db</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">drizzle</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">sqlite</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-name-color)">migrate</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">db</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">migrationsFolder</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./server/db/migrations</span><span style="color:var(--syntax-string-color)">"</span> <span style="color:var(--syntax-text-color)">});</span>
</code></span></span>
下一步是创建数据库模式,在今天的文章中,我们将在数据库中只有一个表,并使用todos三列进行调用,如下所示:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">sqliteTable</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">text</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">integer</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">drizzle-orm/sqlite-core</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">todos</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">sqliteTable</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">todos</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">integer</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">id</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">primaryKey</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">text</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">username</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">notNull</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-name-color)">createdAt</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">integer</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">createdAt</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">notNull</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-text-color)">});</span>
</code></span></span>
上面的代码位于server/db/schema.ts文件中,在创建数据库迁移和作为实体时将考虑该文件。现在让package.json我们添加以下脚本:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-comment-color)">// ...</span>
<span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">scripts</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-comment-color)">// ...</span>
<span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">db:migrations</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">drizzle-kit generate:sqlite --out ./server/db/migrations --schema ./server/db/schema.ts</span><span style="color:var(--syntax-string-color)">"</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-comment-color)">// ...</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
从上面的脚本中,我们可以运行以下命令来创建迁移,同时考虑到创建的架构:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npm run db:migrations
</code></span></span>
一旦完成,预计migrations/将在文件夹内创建该文件夹server/db/。
一旦我们准备好数据层,我们就可以开始处理 GraphQL 层,首先安装这些依赖项:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-comment-color)"># graphql related dependencies</span>
npm <span style="color:var(--syntax-text-color)">install </span>garph graphql-yoga graphql
<span style="color:var(--syntax-comment-color)"># JS Dates</span>
npm <span style="color:var(--syntax-text-color)">install </span>dayjs
</code></span></span>
下一步无疑是使用Garph创建 GraphQL 架构,以创建完全类型安全的 API,而无需进行代码生成。
我们的应用程序的架构将只有一个查询,它将负责返回todos数据库中的所有内容。我们还将有两个 Mutations,一个用于插入 a,todo另一个用于删除现有的todo。
为此,我们创建一个名为gql/in 的server/文件夹,其中包含与我们的架构相关的所有内容,可能类似于以下内容:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">GarphSchema</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">garph</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">g</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">new</span> <span style="color:var(--syntax-name-color)">GarphSchema</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">TodoGQL</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">type</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Todo</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">int</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">string</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-name-color)">createdAt</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">int</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">queryType</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">type</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Query</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">getTodos</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ref</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">TodoGQL</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">list</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-name-color)">description</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Gets an array of todos</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">mutationType</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">type</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Mutation</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">addTodo</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ref</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">TodoGQL</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">args</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">string</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-text-color)">})</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">description</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Adds a new todo</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-name-color)">removeTodo</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ref</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">TodoGQL</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">optional</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">args</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">int</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-text-color)">})</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">description</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Removes an existing todo</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">});</span>
</code></span></span>
使用文件中创建的架构schema.ts,我们现在可以创建resolvers.ts包含查询逻辑和 API 的每个突变的架构。可能如下所示:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">InferResolvers</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">garph</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">YogaInitialContext</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">graphql-yoga</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">eq</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">drizzle-orm</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">dayjs</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">dayjs</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">mutationType</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">queryType</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./schema</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">db</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../db/config</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">todos</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../db/schema</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">type</span> <span style="color:var(--syntax-name-color)">Resolvers</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">InferResolvers</span><span style="color:var(--syntax-error-color)"><</span>
<span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">Query</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">typeof</span> <span style="color:var(--syntax-name-color)">queryType</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-text-color)">Mutation</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">typeof</span> <span style="color:var(--syntax-name-color)">mutationType</span> <span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">context</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">YogaInitialContext</span> <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">resolvers</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">Resolvers</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">Query</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">getTodos</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">_</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">__</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">ctx</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-name-color)">db</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">select</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-declaration-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">todos</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">all</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-name-color)">Mutation</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">addTodo</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">_</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">title</span> <span style="color:var(--syntax-text-color)">},</span> <span style="color:var(--syntax-name-color)">ctx</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-name-color)">db</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">insert</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">todos</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">values</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-name-color)">createdAt</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">dayjs</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-name-color)">unix</span><span style="color:var(--syntax-text-color)">(),</span>
<span style="color:var(--syntax-text-color)">})</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">returning</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">get</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-name-color)">removeTodo</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">_</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">id</span> <span style="color:var(--syntax-text-color)">},</span> <span style="color:var(--syntax-name-color)">ctx</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-name-color)">db</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">delete</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">todos</span><span style="color:var(--syntax-text-color)">).</span><span style="color:var(--syntax-name-color)">where</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">eq</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">todos</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">)).</span><span style="color:var(--syntax-name-color)">returning</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-declaration-color)">get</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">},</span>
<span style="color:var(--syntax-text-color)">};</span>
</code></span></span>
创建模式和解析器后,我们现在需要创建index.ts用于构建 GraphQL 模式的文件,以便 GraphQL Yoga 可以使用它。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">buildSchema</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">garph</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">resolvers</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./resolvers</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">g</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./schema</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">schema</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">buildSchema</span><span style="color:var(--syntax-text-color)">({</span> <span style="color:var(--syntax-name-color)">g</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">resolvers</span> <span style="color:var(--syntax-text-color)">});</span>
</code></span></span>
这样我们就准备好了一切,现在可以跳转到我们将使用包含以下内容的文件router app创建以下文件夹结构的位置:app/api/graphql/route.ts
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">createYoga</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">graphql-yoga</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">schema</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../../../server/gql</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">handleRequest</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">createYoga</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">schema</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-name-color)">graphqlEndpoint</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">/api/graphql</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-name-color)">fetchAPI</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">Request</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">Response</span> <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">handleRequest</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-name-color)">GET</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">handleRequest</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-name-color)">POST</span> <span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
在上面的代码块中,我们创建了一个自定义路由处理程序,它将创建一个GraphQL Yoga实例,该实例将提供我们的 API,同时考虑到刚才创建的架构和解析器。
后端完成后,我们可以继续下一点。
在开始处理页面之前,让我们先处理页面中将使用的一些组件。这些组件与列表和将在其中呈现的元素(行)以及一些操作相关。
首先安装以下依赖项:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>npm <span style="color:var(--syntax-text-color)">install </span>graphql-request zod
</code></span></span>
接下来,让我们创建一个<ListItem />组件,该组件将与列表中的每一行相对应,该列表将在应用程序的根目录中呈现。该组件将接收一些 props,例如todoId、title和一个removeItem()函数。为了具有交互性,该组件将在客户端呈现。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">use client</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">LiHTMLAttributes</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">react</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">interface</span> <span style="color:var(--syntax-name-color)">Props</span> <span style="color:var(--syntax-declaration-color)">extends</span> <span style="color:var(--syntax-name-color)">LiHTMLAttributes</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-name-color)">HTMLLIElement</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">todoId</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">number</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">string</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">removeItem</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">number</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-declaration-color)">void</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">ListItem</span><span style="color:var(--syntax-text-color)">({</span> <span style="color:var(--syntax-name-color)">todoId</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">removeItem</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">...</span><span style="color:var(--syntax-name-color)">rest</span> <span style="color:var(--syntax-text-color)">}:</span> <span style="color:var(--syntax-name-color)">Props</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">li</span>
<span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"card w-96 bg-base-100 shadow-xl cursor-pointer"</span>
<span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">...</span><span style="color:var(--syntax-name-color)">rest</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-name-color)">onClick</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-name-color)">removeItem</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">todoId</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"card-body"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">p</span><span style="color:var(--syntax-text-color)">></span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">p</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">li</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
然后我们可以创建一些将在应用程序列表中使用的操作,我们只需确保这些函数在调用时始终在服务器端运行。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">use server</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">revalidatePath</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">next/cache</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">GraphQLClient</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">gql</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">graphql-request</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">mutation</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">gql</span><span style="color:var(--syntax-string-color)">`
mutation removeTodo($id: Int!) {
removeTodo(id: $id) {
id
}
}
`</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">removeTodo</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">number</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">graphQLClient</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">new</span> <span style="color:var(--syntax-name-color)">GraphQLClient</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">http://localhost:3000/api/graphql</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">await</span> <span style="color:var(--syntax-name-color)">graphQLClient</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">request</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">mutation</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">id</span> <span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-name-color)">revalidatePath</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">/</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
上面的代码是在app/components/文件夹内创建的,更具体地说,list/是在包含文件中的函数的文件夹中创建actions.ts的,并且文件中将包含组件代码index.tsx。该组件仍然需要创建并将在服务器端渲染。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">Infer</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">garph</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">request</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">gql</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">graphql-request</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">TodoGQL</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../../server/gql/schema</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">ListItem</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../ListItem</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">removeTodo</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./actions</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">query</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">gql</span><span style="color:var(--syntax-string-color)">`
query getTodos {
getTodos {
id
title
}
}
`</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">interface</span> <span style="color:var(--syntax-name-color)">QueryData</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-text-color)">getTodos</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">Array</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-name-color)">Infer</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-declaration-color)">typeof</span> <span style="color:var(--syntax-name-color)">TodoGQL</span><span style="color:var(--syntax-error-color)">>></span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">List</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">getTodos</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">await</span> <span style="color:var(--syntax-name-color)">request</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-name-color)">QueryData</span><span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">http://localhost:3000/api/graphql</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-name-color)">query</span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">ul</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"space-y-4"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">getTodos</span><span style="color:var(--syntax-text-color)">?.</span><span style="color:var(--syntax-name-color)">map</span><span style="color:var(--syntax-text-color)">((</span><span style="color:var(--syntax-name-color)">todo</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">ListItem</span>
<span style="color:var(--syntax-name-color)">key</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">todo</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">todo</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-name-color)">todoId</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">todo</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-name-color)">removeItem</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">removeTodo</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-text-color)">/></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">})</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">ul</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
创建可重用组件后,我们现在可以继续下一步。
现在我们已经准备好了需要使用的一切,我们可以开始定义应用程序的路由。我们将在应用程序中使用的路由如下:
app/page.tsx- 应用程序的主路径,我们将在其中列出所有这些内容,并且可以与它们交互以删除它们app/new/page.tsx- 表单出现的位置以及验证提交的数据并进行相应修改的操作现在考虑到这一点,我们可以转到该layout.tsx文件并进行以下更改:
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">./globals.css</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">metadata</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">Today's tasks</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">RootLayout</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">children</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}:</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-text-color)">children</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">React</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">ReactNode</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">})</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">html</span> <span style="color:var(--syntax-name-color)">lang</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"en"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">body</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"h-screen w-screen bg-neutral"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">section</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"container mx-auto p-4"</span><span style="color:var(--syntax-text-color)">></span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">children</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">section</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">body</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">html</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
接下来,在page.tsx文件中,我们将添加一个Suspense边界,以便我们可以利用 html 流,当列表解析异步请求并呈现 html 时,我们将显示一个后备。
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">React</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">Suspense</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">react</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">Link</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">next/link</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">dayjs</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">dayjs</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">List</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">../components/List</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">Page</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"space-y-6"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"flex flex-row items-start justify-between max-w-xl"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">span</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"space-y-2"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">h1</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"text-3xl text-primary-content"</span><span style="color:var(--syntax-text-color)">></span>Today<span style="color:var(--syntax-text-color)">'</span>s tasks<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">h1</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">p</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"text-lg"</span><span style="color:var(--syntax-text-color)">></span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">dayjs</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-name-color)">format</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">dddd, D MMM</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">p</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">span</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">Link</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"btn"</span> <span style="color:var(--syntax-name-color)">href</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"/new"</span><span style="color:var(--syntax-text-color)">></span>
New Task
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-name-color)">Link</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">Suspense</span> <span style="color:var(--syntax-name-color)">fallback</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">span</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"loading loading-ring loading-lg"</span> <span style="color:var(--syntax-text-color)">/></span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">List</span> <span style="color:var(--syntax-text-color)">/></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-name-color)">Suspense</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
最后但并非最不重要的一点是,仍然需要创建负责在文件的文件夹todo内插入新内容的页面。在此组件中,我们将创建一个模式zod来验证表单数据,在该页面内,我们将有一个名为 的函数,该函数应仅在服务器端运行。app/new/page.tsxaddTodo()
<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">Link</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">next/link</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">redirect</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">next/navigation</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">GraphQLClient</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">gql</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">graphql-request</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-name-color)">z</span> <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">zod</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">mutation</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">gql</span><span style="color:var(--syntax-string-color)">`
mutation addTodo($title: String!) {
addTodo(title: $title) {
id
}
}
`</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">formValuesSchema</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">z</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">object</span><span style="color:var(--syntax-text-color)">({</span>
<span style="color:var(--syntax-name-color)">title</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">z</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-declaration-color)">string</span><span style="color:var(--syntax-text-color)">().</span><span style="color:var(--syntax-name-color)">min</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">addTodo</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">formData</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-name-color)">FormData</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">use server</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">formValues</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">{}</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-declaration-color)">any</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-name-color)">key</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">value</span><span style="color:var(--syntax-text-color)">]</span> <span style="color:var(--syntax-declaration-color)">of</span> <span style="color:var(--syntax-text-color)">[...</span><span style="color:var(--syntax-name-color)">formData</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">entries</span><span style="color:var(--syntax-text-color)">()])</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">key</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">includes</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">ACTION_ID</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">))</span> <span style="color:var(--syntax-declaration-color)">continue</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-name-color)">formValues</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-name-color)">key</span><span style="color:var(--syntax-text-color)">]</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">value</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">valueOf</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">parsed</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">await</span> <span style="color:var(--syntax-name-color)">formValuesSchema</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">parseAsync</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">formValues</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">graphQLClient</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-declaration-color)">new</span> <span style="color:var(--syntax-name-color)">GraphQLClient</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">http://localhost:3000/api/graphql</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">await</span> <span style="color:var(--syntax-name-color)">graphQLClient</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">request</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-name-color)">mutation</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">parsed</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-name-color)">redirect</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-string-color)">/</span><span style="color:var(--syntax-string-color)">"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-declaration-color)">function</span> <span style="color:var(--syntax-name-color)">Page</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
<span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"max-w-xs space-y-6"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">Link</span> <span style="color:var(--syntax-name-color)">href</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">".."</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"btn btn-ghost"</span><span style="color:var(--syntax-text-color)">></span>
Go back
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-name-color)">Link</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">form</span> <span style="color:var(--syntax-name-color)">action</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">addTodo</span><span style="color:var(--syntax-string-color)">}</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"space-y-4"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">label</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"label"</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">span</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"label-text"</span><span style="color:var(--syntax-text-color)">></span>Task title<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">span</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">label</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">input</span>
<span style="color:var(--syntax-name-color)">type</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"text"</span>
<span style="color:var(--syntax-name-color)">name</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"title"</span>
<span style="color:var(--syntax-name-color)">placeholder</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"Type here..."</span>
<span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"input input-bordered w-full max-w-xs"</span>
<span style="color:var(--syntax-name-color)">required</span>
<span style="color:var(--syntax-name-color)">minLength</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-string-color)">}</span>
<span style="color:var(--syntax-text-color)">/></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">button</span> <span style="color:var(--syntax-name-color)">className</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"btn btn-block"</span> <span style="color:var(--syntax-name-color)">type</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"submit"</span><span style="color:var(--syntax-text-color)">></span>
Submit
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">button</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">form</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
<span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>
至此,我结束了本文的最后一步。
我希望您觉得这篇文章很有帮助,无论您是在现有项目中使用这些信息还是只是为了好玩而尝试一下。