在 Vue 3 + Vite 中接入 InstantDB:从环境配置、Schema 同步到实时查询的完整实战指南
【免费下载链接】instantInstant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.项目地址: https://gitcode.com/gh_mirrors/inst/instant
本文以examples/vue-vite这个官方示例为蓝本,完整讲解如何在一个 Vue 3 + Vite 工程中初始化 InstantDB 客户端、通过instant-cli同步数据模型(Schema)、配置VITE_INSTANT_APP_ID环境变量,并借助useAuth、useQuery、transact等响应式 API 实现邮箱验证码登录与实时待办事项(Todos)应用。读完本文,你将掌握 InstantDB 在 Vue 项目中的标准接入流程,并理解其底层运行机制,可直接照搬到自己的 Vue 应用中。
示例项目概览与技术栈
仓库中的examples/vue-vite是一个开箱即用的官方示例,从 package.json 可以看到它的技术选型:
- 前端框架:Vue
^3.5.0(使用<script setup lang="ts">组合式 API 与 TypeScript); - 构建工具:Vite
^7.1.4,配合@vitejs/plugin-vue、vite-plugin-vue-devtools; - 样式方案:Tailwind CSS
^4.1.13,通过@tailwindcss/vite插件接入,示例入口在 src/assets/main.css; - 核心依赖:
@instantdb/vue,即 InstantDB 官方 Vue 绑定; - Node 版本要求:
^20.19.0 || >=22.12.0(见package.json的engines字段),安装前请确认本地 Node 版本满足条件。
项目文件结构如下:
examples/vue-vite/ ├── index.html # Vite 入口 HTML,挂载 #app ├── vite.config.ts # Vite 配置(Vue 插件、Tailwind、@ 别名) ├── env.d.ts # Vite 客户端类型引用 ├── package.json # 依赖与脚本 ├── tsconfig*.json # TypeScript / vue-tsc 工程配置 └── src/ ├── main.ts # 应用启动入口 ├── App.vue # 唯一的业务组件(登录 + Todos) ├── instant.schema.ts # 数据模型定义 ├── instant.perms.ts # 权限规则 ├── lib/db.ts # InstantDB 客户端初始化 └── assets/main.css # 全局样式(Tailwind)入口 src/main.ts 与普通的 Vue 应用并无区别——引入全局样式后createApp(App).mount('#app');真正的 InstantDB 接入发生在src/lib/db.ts和App.vue中,下文逐步展开。
第一步:安装依赖
在examples/vue-vite目录下执行:
npm install该命令会安装@instantdb/vue、vue以及全部开发依赖(Vite、vue-tsc、Tailwind、npm-run-all2等)。若你的项目使用 pnpm,同样可以用pnpm install安装(仓库根目录即采用 pnpm workspace 管理,参见根目录的 pnpm-workspace.yaml)。
第二步:配置 VITE_INSTANT_APP_ID 环境变量
这是运行前必须完成的一步。示例 README.md 明确指出:
Set
VITE_INSTANT_APP_IDin an.envfile before running the app.
在项目根目录创建.env文件,写入:
VITE_INSTANT_APP_ID=你的应用IDVITE_前缀是 Vite 暴露给客户端代码的环境变量约定:只有以VITE_开头的变量才会被import.meta.env读取,并出现在打包产物中。该值在 src/lib/db.ts 中被消费:
import { init } from "@instantdb/vue"; import schema from "../instant.schema"; export const db = init({ appId: import.meta.env.VITE_INSTANT_APP_ID!, schema, useDateObjects: true, });要点说明:
appId是你在 InstantDB 控制台创建应用后获得的标识符,用于关联云端数据库;- 使用非空断言
!表示该变量必然存在——这正是要求“先配置.env再运行”的原因; useDateObjects: true表示时间字段以 JavaScriptDate对象返回而非字符串。
从 client/packages/vue/src/InstantVueDatabase.ts 的init源码可以看到,init实际调用核心包的core_init创建底层数据库实例,再包装为InstantVueDatabase,所有 Vue 响应式 API(useQuery、useAuth等)都挂在这个实例上:
export function init<...>(config: ...): InstantVueDatabase<Schema, UseDates> { const coreDb = core_init<Schema, UseDates>(config, undefined, undefined, { '@instantdb/vue': version, }); return new InstantVueDatabase<Schema, UseDates>(coreDb); }建议将.env加入.gitignore,避免应用 ID 等敏感配置入库。
第三步:启动开发服务器
npm run dev该命令实际执行vite(见 package.json 的scripts),启动后即可在浏览器访问本地地址。首次打开页面会看到登录界面,因为App.vue通过db.useAuth()判断用户状态——未登录时渲染“Sign in”表单,已登录时渲染 Todos 面板。
第四步:同步 Schema(数据模型)
InstantDB 采用“Schema 即代码”的模型驱动方式:你在src/instant.schema.ts中声明实体、字段、链接和房间,然后通过instant-cli推送到云端。
推送 Schema
npx instant-cli push该命令将本地 src/instant.schema.ts 中定义的模型推送到与你VITE_INSTANT_APP_ID对应的云端数据库。
拉取 Schema
npx instant-cli pull反向操作:把云端当前的 Schema 同步到本地文件。当你与团队成员协作、或有人在控制台手动改过模型时,用pull保证本地定义与云端一致。
示例 Schema 详解
src/instant.schema.ts 使用了@instantdb/vue导出的类型安全构造器i:
import { i } from "@instantdb/vue"; const _schema = i.schema({ entities: { $files: i.entity({ path: i.string().unique().indexed(), url: i.string(), }), $users: i.entity({ email: i.string().unique().indexed().optional(), imageURL: i.string().optional(), type: i.string().optional(), }), todos: i.entity({ createdAt: i.number(), done: i.boolean(), text: i.string(), }), }, links: { $usersLinkedPrimaryUser: { forward: { on: "$users", has: "one", label: "linkedPrimaryUser", onDelete: "cascade", }, reverse: { on: "$users", has: "many", label: "linkedGuestUsers", }, }, }, rooms: {}, });几个值得注意的点:
- 内置实体:
$files(文件存储)与$users(用户)是 InstantDB 预置的系统实体,这里对它们补充了字段约束,例如$users.email声明为unique().indexed().optional()——邮箱唯一、建索引、可缺失; - 业务实体:
todos定义了createdAt(数字时间戳)、done(布尔)、text(字符串)三个字段,字段类型由i.number()、i.boolean()、i.string()声明; - 链接(links):示例声明了
$usersLinkedPrimaryUser自关联,forward表示一个用户拥有一个linkedPrimaryUser,reverse表示一个用户可被多个linkedGuestUsers关联,且主用户删除时级联删除(onDelete: "cascade"); - 房间(rooms):
rooms: {}目前为空,可在此声明房间类型以使用 Presence 与 Topics 能力; - 类型导出技巧:通过
interface AppSchema extends _AppSchema {}包装类型,能让 TypeScript 的智能提示更友好,同时export type { AppSchema }供其他文件(如App.vue)引用。
权限规则文件
src/instant.perms.ts 定义了应用的权限规则,当前为“空规则”占位:
import type { InstantRules } from "@instantdb/vue"; const rules = { /** * posts: { * allow: { * view: "true", * create: "isOwner", * update: "isOwner", * delete: "isOwner", * }, * bind: {"isOwner": "auth.id != null && auth.id == data.ownerId"}, * }, */ } satisfies InstantRules; export default rules;文件中的注释给出了规则语法示例:allow配置view/create/update/delete四个操作的表达式,bind则把可复用的判断(如isOwner)绑定为auth与data的表达式。规则为空意味着当前未做额外限制,生产环境应参照该语法补全,以控制谁能读取、创建、修改或删除数据。
第五步:理解核心业务代码(App.vue)
src/App.vue 是示例唯一的业务组件,完整演示了 InstantDB Vue 绑定的三大核心 API。
1. 响应式认证:useAuth
const { isLoading: authLoading, user } = db.useAuth();useAuth订阅登录状态,返回isLoading、user、error三个响应式引用。从 client/packages/vue/src/InstantVueDatabase.ts 的实现可以看到,它通过subscribeAuth订阅核心层的认证状态,并把结果写入ref/shallowRef,同时tryOnScopeDispose保证组件卸载时自动取消订阅。模板中据此三分支渲染:
<div v-if="authLoading">Loading...</div> <div v-else-if="user">...Todos 面板...</div> <div v-else>...登录表单...</div>即:认证加载中显示 Loading,已登录显示业务界面,未登录显示登录界面。
2. 邮箱验证码登录
示例使用 InstantDB 的 Magic Code 认证流程。发送验证码:
function sendCode() { if (!email.value) return; const target = email.value; db.auth .sendMagicCode({ email: target }) .then(() => { sentEmail.value = target; }) .catch((err: any) => { alert("Error sending code: " + (err.body?.message ?? err.message)); }); }验证验证码并登录:
function verifyCode() { if (!code.value || !sentEmail.value) return; db.auth .signInWithMagicCode({ email: sentEmail.value, code: code.value }) .catch((err: any) => { alert("Error verifying code: " + (err.body?.message ?? err.message)); code.value = ""; }); }界面流程为:输入邮箱 →sendMagicCode发送验证码 → 输入收到的验证码 →signInWithMagicCode完成登录;登录后可通过db.auth.signOut()退出。错误处理统一从err.body?.message兜底到err.message,这是因为 InstantDB 服务端错误通常携带结构化响应体。
3. 实时查询:useQuery
const { isLoading: queryLoading, error, data } = db.useQuery({ todos: {} });useQuery接收 InstaQL 查询对象,返回isLoading、data、pageInfo、error四个响应式引用。{ todos: {} }表示“查询全部 todos 数据”。关键特性是实时性:查询建立后,任何客户端(甚至其他浏览器标签页)对todos的写入都会推送到当前订阅者——这正是示例界面中那句 “Open another tab to see todos update in realtime!” 的含义。
从 client/packages/vue/src/InstantVueDatabase.ts 的实现可以看出它的响应式设计:
- 查询可以是普通对象、
ref或 getter 函数(MaybeRefOrGetter),内部通过toValue归一化; - 用
computed计算查询哈希,watch监听哈希变化后调用subscribeQuery订阅,并在回调中更新data、pageInfo、error; - 组件卸载时通过
onCleanup取消订阅,tryOnScopeDispose兜底清理。
因此示例还支持“响应式查询”——例如根据当前登录用户动态过滤(源码注释中的示例):
const { data } = db.useQuery(() => user.value ? { todos: { $: { where: { 'owner.id': user.value.id } } } } : null, );当user未登录时传入null跳过查询,登录后自动发起带where条件的查询。
4. 数据写入:transact与db.tx
useQuery负责读,transact负责写。示例展示了新增、更新、删除、批量删除四种操作:
// 新增:id() 生成唯一主键,update 设置字段 db.transact( db.tx.todos[id()].update({ text: value, done: false, createdAt: Date.now(), }), ); // 更新:按主键定位并翻转 done db.transact(db.tx.todos[todo.id].update({ done: !todo.done })); // 删除单条 db.transact(db.tx.todos[todo.id].delete()); // 批量删除(一次事务删除所有已完成项) db.transact(completed.map((t) => db.tx.todos[t.id].delete()));写法上形成“db.tx.实体[主键].操作(...)”的链式约定:id()用于生成新的随机主键,update写入或覆盖字段,delete删除记录。transact接收单个事务或事务数组,并保证一次性提交。得益于@instantdb/vue的类型定义,db.tx.todos的字段与instant.schema.ts中todos实体完全对齐,text、done、createdAt的类型错误会在编译期暴露。配合InstaQLEntity泛型:
type Todo = InstaQLEntity<AppSchema, "todos">;组件内即可获得todo.text、todo.done、todo.id的完整类型提示。
第六步:构建与类型检查
除开发命令外,示例还提供完整的构建脚本(见 package.json):
npm run build # 类型检查 + 构建 npm run preview # 预览构建产物其中build由run-p type-check "build-only {@}" --组成,即并行执行vue-tsc --build(类型检查)与vite build(产物构建);tsconfig采用@vue/tsconfig基线并配置了@/*路径别名(见 tsconfig.app.json 与 vite.config.ts 的resolve.alias),类型检查的增量缓存文件被显式写到node_modules/.tmp下以避免污染根目录。
运行流程小结
把以上步骤串起来,一次完整的接入流程是:
npm install安装依赖;- 创建
.env并设置VITE_INSTANT_APP_ID; - 编辑
src/instant.schema.ts定义实体与链接,必要时补充src/instant.perms.ts权限规则; npx instant-cli push将 Schema 推送到云端;npm run dev启动开发服务器,通过db.useAuth()处理登录、db.useQuery()实时读取数据、db.transact()写入数据;- 上线前用
npm run build做类型检查与构建。
如果后续在控制台或其他地方修改了模型,随时用npx instant-cli pull把云端 Schema 拉回本地,保持代码与云端一致。这套“Schema 即代码 + CLI 双向同步 + 响应式 Hook”的流程,就是 InstantDB 在 Vue 3 + Vite 项目中的标准集成姿势,本仓库的 examples/vue-vite 目录可以直接作为新项目脚手架使用。
【免费下载链接】instantInstant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.项目地址: https://gitcode.com/gh_mirrors/inst/instant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考