写给前端的Vue+Prisma+tRPC入门指南
写在前面这是给前端实验室实习生培训前写的教案及入门指南因为实验室一个比赛由于各部门人数不均问题导致部分前端实习生没有后端配合遂得让他们自己写…写完后觉得应该值得记录一下本人也只是全栈半吊子甚至还没入门水平教案部分源自ai并稍加修改了些许如有错误敬请指正哦对最后说一句本来这个文档是docx格式塞进来不是很方便观看如有需要可找我发原docx^^极简操作指南可复制代码在文档最后面 熟悉后整套配置流程需大约4分钟第一阶段项目初始化1.1 创建项目并安装核心依赖WinR 输入cmd…1.2初始化 Prismanpx prisma init --datasource-provider sqlite第二阶段 Schema2.1编写数据库模型 代码见下2.2创建数据库表npx prisma migrate dev第三阶段后端实现3.1 创建服务器文件根目录下创建server文件夹并在文件夹下新建index.ts文件代码见下3.2 启动后端服务npx tsx server/index.ts第四阶段前端配置与调用4.1 配置 Vite 代理解决跨域 根目录下vite.config.ts文件4.2创建 tRPC 客户端src文件夹下新建utils文件夹并新建trpc.ts4.3 Vue 组件中使用PrismatRPC编写一个简单的数据存取组件并实现前后端互联新建终端CtrlShift~ 非常好用的快捷键输入npm run dev 启动前端教案主要是一些比较概念性的东西 理解使用tRPC和Prisma的优点即可一、 培训目标与大纲培训目标• 理解全栈类型安全掌握从前端到后端的完整类型推断避免前后端接口字段不一致。• 掌握 Prisma 基本操作学会初始化客户端、进行简单的增删改查CRUD以及理解 ORM 的作用。• 掌握 tRPC 基础理解定义路由Router和在 Vue 中调用接口的流程。培训大纲1. 背景引入与架构对比10分钟2. Prisma 基础与快速上手15分钟3. tRPC 基础路由与上下文20分钟4. Vue 前端集成与类型推断10分钟5. QA 与总结5分钟________________________________________二、 详细教学内容与执行步骤1. 背景引入与架构对比10分钟核心知识点• 什么是 tRPC它是一个允许你在前后端之间共享类型而无需生成 OpenAPI 规范或 GraphQL 模式的 RPC远程过程调用框架。• 痛点解决传统开发中后端修改字段前端如果不手动同步很容易导致运行时报错。tRPC 可以实现“全栈类型安全”。教学讲解要点1. 学员回顾现有的 Vue 开发经验平时如何定义 Axios 请求和接口返回类型。2. 问题“如果后端改了一个字段名字前端要改几处”引出 tRPC 的核心优势。3. 强调本节课的目标是完成一个从 Vue 到 tRPC 路由再到 Prisma 查询数据库的闭环。________________________________________2. Prisma 基础与快速上手15分钟核心知识点• Schema 文件定义如何在 Prisma 中定义模型。• 数据库迁移使用 prisma migrate dev 同步数据库。• Prisma Client生成强类型的查询客户端。示例代码定义一个简单的用户模型教学执行细节1. 使用命令行执行初始化npx prisma init2. 生成客户端 npx prisma migrate dev --name init3. Prisma 具有强类型优势写查询时 IDE 就会有补全提示减少拼写错误。________________________________________3. tRPC 基础路由与上下文20分钟核心知识点• 初始化 tRPC创建 tRPC 实例。• 定义 Router实现查询Query和修改Mutation。示例代码定义 tRPC 路由教学执行细节1. Zod 校验说明Zod 在这里不仅用于校验输入参数的合法性更重要的作用是为前端提供对应的 TypeScript 类型推断。2. query 与 mutation 的区别这与 Vue 应用里的 GET 和 POST 概念类似。________________________________________4. Vue 前端集成与类型推断10分钟核心知识点• 如何在 Vue 项目中实例化 tRPC 客户端。示例代码Vue 组件中使用Ts部分Template部分注1. 在 Vue 中可以直接像调用普通函数一样调用 tRPC 方法且 IDE 会检查类型和参数。2. 如果后端修改了 Schema 字段名称前端代码在保存时就会立刻标红报错极大降低了维护成本。长代码部分1.1# 创建项目npm create vitelatest Lesson6-fullStack# 勾选各选项...# 安装核心依赖npm install -D prisma6.5.0npm install prisma/client6.5.0# tRPCnpm install trpc/server trpc/client# Zod 数据验证npm install zod# tsx 运行时npm install -D tsx2.1generator client {provider prisma-client-js}datasource db {provider sqliteurl env(DATABASE_URL)}model Student {id Int id default(autoincrement()) // 主键自增studentNumber String unique // 学号唯一约束name String // 姓名}3.1// server/index.tsimport z from zod;import { createHTTPServer } from trpc/server/adapters/standalone;import { initTRPC } from trpc/server;import { PrismaClient } from prisma/client;// 初始化const prisma new PrismaClient();// 初始化 tRPCconst t initTRPC.create();const router t.router;const publicProcedure t.procedure;const appRouter router({getStudents: publicProcedure.query(async () {return await prisma.student.findMany();}),createStudent: publicProcedure.input(z.object({studentNumber: z.string(),name: z.string(),})).mutation(async ({ input }) {return await prisma.student.create({ data: input });}),});export type AppRouter typeof appRouter;// 启动服务器const server createHTTPServer({ router: appRouter });server.listen(3000, () {console.log( 后端服务运行在 http://localhost:3000);});4.1import { defineConfig } from viteimport vue from vitejs/plugin-vue// https://vite.dev/config/export default defineConfig({plugins: [vue()],server: {proxy: {/api: {target: http://localhost:3000,changeOrigin: true,rewrite: (path) path.replace(/^\/api/, ),},},},})4.2// src/utils/trpc.tsimport { createTRPCProxyClient, httpBatchLink } from trpc/client;import type { AppRouter } from ../../server;export const trpc createTRPCProxyClientAppRouter({links: [httpBatchLink({ url: /api })],});4.3script setup langtsimport { ref, onMounted } from vue;import { trpc } from ./utils/trpc;const students refany[]([]);const loading ref(false);const form ref({studentNumber: ,name: });const loadStudents async () {loading.value true;try {students.value await trpc.getStudents.query();} catch (err) {console.error(加载失败:, err);} finally {loading.value false;}};const addStudent async () {if (!form.value.studentNumber || !form.value.name) {alert(请输入完整)return;}try {await trpc.createStudent.mutate({studentNumber: form.value.studentNumber,name: form.value.name,});form.value { studentNumber: , name: };await loadStudents();alert(添加成功);} catch (err) {console.error(添加失败:, err);}}onMounted(() loadStudents());/scripttemplatediv学号:input typetext v-modelform.studentNumber姓名:input typetext v-modelform.namebutton clickaddStudent添加学生/button/divtabletheadtrth姓名/ththid/thth学号/th/tr/theadtbodytr v-forstu in studentstd{{ stu.name }}/tdtd{{ stu.id }}/tdtd{{ stu.studentNumber }}/td/tr/tbody/table/template
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2599233.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!