
Instant Vue 沙箱应用实战基于 instantdb/vue 的本地后端开发与实时功能全解析【免费下载链接】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本文以仓库中 client/sandbox/vue-vite 沙箱应用为实例完整讲解如何在不配置任何环境变量的前提下用 Vue 3 Vite instantdb/vue快速搭建一个对接本地 Instant 后端的实时应用。读完本文你将掌握 Instant 的临时应用ephemeral app启动机制、useQuery/transact的增删改查范式以及 auth 认证、Cursors 光标同步、无限滚动查询与输入指示器等完整实战用法。沙箱应用定位与仓库结构client/sandbox/vue-vite是 Instant 官方仓库中用于体验 Vue SDK 的沙箱应用sandbox其唯一目的就是play withinstantdb/vue。它不是一个需要申请 App ID 的正式示例而是为本地开发与功能验证设计的即开即用环境。从仓库结构看应用主体是一个标准 Vite Vue 3 项目client/sandbox/vue-vite/ ├── index.html # 入口 HTML挂载 #app ├── package.json # 依赖与脚本dev / build / preview / type-check ├── vite.config.ts # vue 插件 Tailwind v4 别名 ├── tsconfig*.json # TypeScript / vue-tsc 配置 └── src/ ├── main.ts # createApp router 挂载 ├── App.vue # 仅渲染 RouterView / ├── router.ts # 路由表 ?app 参数保持 ├── lib/ │ ├── config.ts # 本地后端 apiURI / websocketURI │ └── db.ts # schema 定义 临时应用生命周期 init ├── assets/main.css └── pages/ # Home / Todos / Auth / Cursors / InfiniteScroll / Typing依赖方面package.json 显示它直接以workspace:*引入instantdb/vue配合vue ^3.5.0与vue-router ^4.4.0开发依赖使用 Vite 6、vitejs/plugin-vue、tailwindcss/viteTailwind CSS v4 的 Vite 插件形态以及vue-tsc做类型检查。快速启动一条命令免去全部环境配置README 给出的启动步骤非常精简核心前提只有一个——本地已有一个运行在 8888 端口的 Instant 后端pnpm install pnpm dev启动后打开http://localhost:5173应用会自动为你创建一个临时应用ephemeral app不需要任何.env配置。这一点与常规示例需要VITE_INSTANT_APP_ID的做法形成鲜明对比可对照 client/packages/vue/README.md 中init({ appId: import.meta.env.VITE_INSTANT_APP_ID })的常规用法。为什么不需要环境变量因为沙箱的整套逻辑建立在向本地后端动态申请应用 ID之上详见下文源码分析。开发服务器默认端口 5173 由 Vite 决定index.html与vite.config.ts中均未改端口。免配置的奥秘临时应用Ephemeral App机制沙箱的核心设计都集中在 src/lib/db.ts它替代了人工去控制台创建 App 再填 App ID的流程整个过程分为四个环节1. 本地后端地址与 WebSocketsrc/lib/config.ts 通过 Vite 环境变量VITE_LOCAL_SERVER_PORT默认8888派生两个关键地址const config { apiURI: http://localhost:${localPort}, websocketURI: ws://localhost:${localPort}/runtime/session, }; export default config;apiURIHTTP 接口用于创建/校验临时应用、发起 REST 类请求websocketURI/runtime/session是即时数据同步实时查询、presence的 WebSocket 会话端点。如果你本地的后端端口不是 8888只需在启动时注入VITE_LOCAL_SERVER_PORTxxxx pnpm dev即可无需改动代码。2. 用 schema 申请一个应用db.ts首先用i.schema定义数据模型并在启动时直接把这个 schema 作为建表请求发给本地后端const schema i.schema({ entities: { todos: i.entity({ text: i.string(), done: i.boolean(), createdAt: i.number(), }), items: i.entity({ value: i.number().indexed(), // 为无限滚动查询建立索引 }), }, });然后通过 POST/dash/apps/ephemeral创建临时应用把 schema 一并上传db.ts 中的provisionEphemeralAppconst r await fetch(${config.apiURI}/dash/apps/ephemeral, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ title: Vue Sandbox, schema }), });后端会返回一个app.id这个 ID 就是后续init()所需的 App ID。整个过程说明Instant 的 schema 不仅用于客户端类型推导也能直接驱动服务端建表——这正是沙箱能做到零配置的关键。3. 应用 ID 的复用与校验URL 参数优先getOrCreateAppId实现了三级取 ID 策略db.ts优先读 URL 上的?appid这样共享链接可以跨标签页、跨用户指向同一个应用方便多人联调实时功能其次读localStorage中缓存的sb-vue-vite-ephemeral-app-id都没有或校验失败时才重新provisionEphemeralApp创建一个全新的临时应用。其中校验通过 GET/dash/apps/ephemeral/:appId完成verifyEphemeralApp如果后端返回错误例如临时应用已被清理就静默降级为重新创建保证应用始终可用。拿到 ID 后通过persistAppId写回 URL 与 localStorage方便下次刷新继续使用同一个应用。4. 初始化 db 与重置db.value init({ ...config, appId, schema, devtool: false, // 沙箱场景关闭 devtool 弹层 });db.ts把db、isLoading、error以 Vueref/shallowRef导出所有页面组件如 Todos.vue都会先渲染Creating ephemeral app...加载态再在db就绪后进入功能界面。此外还导出了resetEphemeralApp()清除 localStorage 中的应用 ID、从 URL 删掉?app然后location.reload()重新申请一个全新应用——相当于换个数据库重来非常适合反复测试。5. 路由守卫保持同一应用由于应用 ID 挂在 URL 查询参数上router.ts 特意加了全局前置守卫保证导航如从/跳到/cursors时?appid不丢失否则目标页面会误以为没有 ID 而重新申请新应用router.beforeEach((to) { if (to.query.app) return; const currentApp new URLSearchParams(window.location.search).get(app); if (!currentApp) return; return { ...to, query: { ...to.query, app: currentApp } }; });这也是一个非常实用的工程细节当应用状态以 URL 参数承载时路由中间件需要显式维持参数跨页面传递。路由清单六个页面覆盖 Instant 六大能力README 列出了三条核心路由而仓库实际的路由表router.ts更完整共六条全部围绕instantdb/vue的核心能力设计路由组件验证的能力/Home.vue导航首页说明?app共享机制/todosTodos.vue / TodoApp.vue实时 CRUDtodo 应用/authAuth.vueSignedIn/SignedOut组件与魔法码登录/cursorsCursors.vue多人光标实时同步presence/infinite-scrollInfiniteScroll.vue / InfiniteScrollDemo.vueuseInfiniteQuery分页加载/typingTyping.vue / TypingDemo.vue实时输入指示器typing indicator其中/todos、/auth、/cursors正是 README 明示的三条测试路由/infinite-scroll与/typing则是仓库源码中补充的进阶示例。实时 CRUDTodo 应用的读写范式TodoApp.vue 是 Instant 数据读写的最小完整范例三行核心 API 覆盖读-写-删// 1. 读响应式订阅查询数据变更实时回流 const { isLoading, error, data } props.db.useQuery({ todos: {} }); const todos computed(() data.value?.todos ?? []); const remaining computed(() todos.value.filter((t) !t.done).length); // 2. 写transact tx 链式构造事务 props.db.transact( props.db.tx.todos[id()].update({ text: value, done: false, createdAt: Date.now(), }), ); // 3. 删按 id 构造删除事务也支持批量 props.db.transact(props.db.tx.todos[todo.id].delete()); props.db.transact(completed.map((t) props.db.tx.todos[t.id].delete()));要点拆解useQuery({ todos: {} })返回isLoading / error / data三个响应式值Vue 版本返回ref模板中自动解包订阅建立后任何客户端写入或其他端点的写入都会即时推送id()用于生成全局唯一实体 IDtx.todos[id()].update(...)是不存在即创建的 upsert 语义批量操作只需给transact传入事务数组类型层面通过InstaQLEntityAppSchema, todos拿到严格类型的实体AppSchema由typeof schema推导而来db.ts。页面顶部文案Open another tab to see todos update in realtime!提示了正确的验证方式由于?app可共享复制当前 URL 到另一个标签页即可看到两端的实时双向同步。认证SignedIn / SignedOut 组件与魔法码登录Auth.vue 演示了 Instant 的邮箱魔法码认证流程并验证instantdb/vue内置的两个条件渲染组件SignedOut :dbdb !-- 未登录时渲染发送验证码表单 -- /SignedOut SignedIn :dbdb !-- 已登录时渲染用户信息 登出按钮 -- /SignedIn登录逻辑分为两步Auth.vue// 第一步发送魔法码 db.value.auth.sendMagicCode({ email: target }); // 第二步提交收到的验证码 db.value.auth .signInWithMagicCode({ email: sentTo.value, code: code.value }) .catch(() { code.value ; });sendMagicCode会向邮箱发送一次性验证码signInWithMagicCode校验后建立会话组件树中的SignedIn随即接管渲染db.auth.signOut()一键登出。这两个组件与Cursors一样都是instantdb/vue从 index.ts 直接导出的内置 Vue 组件。多人实时Cursors 光标同步Cursors.vue 演示了 Instant 的 presence在线状态能力——把任意页面变成共享协作画布const room computed(() db.value?.room(main as any, cursors-demo));Cursors v-else-ifroom :roomroom classmin-h-screen !-- 包在 Cursors 内的任意内容都会显示其他在线用户的光标 -- /Cursors机制说明db.room(main, cursors-demo)建立命名房间Cursors组件订阅该房间内所有 peer 的光标位置并渲染为移动的鼠标指针。页面提示Open this page in multiple tabs to see cursors from other users配合首页介绍的?app共享 URL 方案即可在两个标签页/两台设备上看到彼此的光标移动。Cursors组件实现在 client/packages/vue/src/components/Cursors.vue配套的Cursor.vue负责单个指针的渲染细节。无限滚动useInfiniteQuery 分页加载InfiniteScrollDemo.vue 是 README 未列出但源码中最重要的进阶示例之一验证useInfiniteQuery的按需加载 方向敏感特性const pageSize 4; const scrollResult props.db.useInfiniteQuery({ items: { $: { limit: pageSize, order: { value: asc } }, }, }); // 返回值isLoading / data / error / canLoadNextPage / loadNextPage页面布局非常聪明地模拟了数轴场景Add new lowest插入比当前最小值还小的值value - 1Add new highest插入比当前最大值还大的值value 1Load more按钮通过loadNextPage()继续翻页canLoadNextPage控制按钮禁用态右侧面板实时展示分页诊断数据canLoadNextPage/isLoading/loaded数量。这验证了一个关键设计无限查询对插入位置敏感——在已加载窗口上方插入新值会改变第一页内容因此页面把所有写入放进writeQueue串行队列enqueue并用queryOnce读取最新快照再插入保证演示时数据的一致性。底层实现可参考 client/packages/vue/src/useInfiniteQuery.ts它通过watch监听 query 与 options 的weakHash变化变化即取消旧订阅并重建每次响应回调只更新data与canLoadNextPage真正的游标分页由 core 层subscribeInfiniteQuery完成。输入指示器useTypingIndicator 与 useSyncPresenceTypingDemo.vue 演示了另一个 presence 应用——对方正在输入const userId id(); const room props.db.room(typing-indicator-example as any, 1234); // 1. 把自己注册进房间 props.db.rooms.useSyncPresence(room as any, { id: userId }); // 2. 订阅该房间的输入状态拿到绑定到 textarea 的事件处理器 const { active, inputProps } props.db.rooms.useTypingIndicator( room as any, chat-input, );模板中把inputProps.onKeydown/inputProps.onBlur直接绑定到textareaactive数组即为正在输入的其他用户列表配合typingInfo()生成1 person is typing...之类的文案。整个过程无需自己设计 WebSocket 消息协议Instant 的 rooms API 已封装了状态广播与过期清理。instantdb/vue SDK 导出全景所有页面用到的 API 均来自同一个包入口 client/packages/vue/src/index.ts它从instantdb/core重导出核心能力并补充 Vue 专属封装。常用导出可归纳为初始化与实体init、ischema 构造器、id、tx、lookupVue 组件SignedIn、SignedOut、CursorsVue 响应式封装InstantVueDatabase即init的返回类型含useQuery/transact/room等、InstantVueRoom含useSyncPresence/useTypingIndicator类型体系InstantSchema、InstaQLEntity、Query、AuthState、PresencePeer等全套 TS 类型保证 schema 驱动的端到端类型安全。工程配置要点TypeScriptvue-tsc --build提供类型检查见 package.json 的type-check脚本Node 版本要求^20.19.0 || 22.12.0Tailwind CSS v4通过tailwindcss/vite插件接入无需单独的tailwind.config.js类名直接在组件模板中使用vite.config.ts构建脚本devvite、build先类型检查再构建、preview预览产物。总结与延伸从本沙箱可以提炼出一套可复用的 Instant 本地开发方法论零配置联调借助 ephemeral app 接口POST/GET /dash/apps/ephemeral客户端 schema 即可驱动后端建库建表无需手动申请 App ID状态承载于 URL?appid让实时功能cursors、typing、多端 CRUD可以跨标签页、跨设备无缝共享同时需要路由守卫维持参数一套 API 覆盖全场景useQuerytransact解决数据读写SignedIn/SignedOut解决认证Cursors/useTypingIndicator解决协作useInfiniteQuery解决大数据集分页。如果你想在自己的 Vue 项目中使用正式环境可参考 client/packages/vue/README.md 的init({ appId })标准初始化方式而需要体验完整功能时随时可以回到本沙箱pnpm install pnpm dev后即可开始把玩instantdb/vue的每一项能力。【免费下载链接】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),仅供参考