快速开始
这份文档只做一件事:帮你用最短路径跑通 RxDB 的本地数据链路。
第一次接触时,先别看同步、分支、协作。先跑通主线——模型定义 → 本地数据库 → 查询 → 写入 → UI 绑定——这也是当前仓库里最稳定、最容易验证的那一段。
跑通后你会确认
- 浏览器内真实的关系型数据库能力
- 响应式查询与写入链路
- 类型安全的实体模型
- Angular / React / Vue 三套对等接口
想先看现成应用
仓库根目录已经有可运行的 demo,任选一个启动即可:
pnpm nx serve dev-rxdb-angular
pnpm nx serve dev-rxdb-react
pnpm nx serve dev-rxdb-vue
如果你更想从最小代码开始,继续往下读。
安装
核心包
- npm
- Yarn
- pnpm
- Bun
npm install @aiao/rxdb @aiao/rxdb-adapter-wa-sqlite
yarn add @aiao/rxdb @aiao/rxdb-adapter-wa-sqlite
pnpm add @aiao/rxdb @aiao/rxdb-adapter-wa-sqlite
bun add @aiao/rxdb @aiao/rxdb-adapter-wa-sqlite
框架集成(按需)
- npm
- Yarn
- pnpm
- Bun
# React
npm install @aiao/rxdb-react
# Vue 3
npm install @aiao/rxdb-vue
# Angular
npm install @aiao/rxdb-angular
# React
yarn add @aiao/rxdb-react
# Vue 3
yarn add @aiao/rxdb-vue
# Angular
yarn add @aiao/rxdb-angular
# React
pnpm add @aiao/rxdb-react
# Vue 3
pnpm add @aiao/rxdb-vue
# Angular
pnpm add @aiao/rxdb-angular
# React
bun add @aiao/rxdb-react
# Vue 3
bun add @aiao/rxdb-vue
# Angular
bun add @aiao/rxdb-angular
完整的环境要求、WASM 路径与 Vite 配置详见 安装与初始化。
最小可运行示例
1. 定义数据模型
import { Entity, EntityBase, PropertyType } from '@aiao/rxdb';
@Entity({
name: 'Todo',
properties: [
{ name: 'title', type: PropertyType.string, required: true },
{ name: 'completed', type: PropertyType.boolean, default: false },
{ name: 'createdAt', type: PropertyType.date }
]
})
export class Todo extends EntityBase {}
模型一旦定好,后续的查询、写入、类型推断都会围绕它展开。
2. 初始化数据库
import { RxDB, SyncType } from '@aiao/rxdb';
import { RxDBAdapterWaSqlite } from '@aiao/rxdb-adapter-wa-sqlite';
import { checkOPFSAvailable } from '@aiao/utils';
const rxdb = new RxDB({
dbName: 'myapp',
entities: [Todo],
sync: { local: { adapter: 'wa-sqlite' }, type: SyncType.None }
});
rxdb.adapter('wa-sqlite', async db => {
const available = await checkOPFSAvailable();
return new RxDBAdapterWaSqlite(db, {
vfs: available ? 'OPFSCoopSyncVFS' : 'IDBBatchAtomicVFS',
worker: available,
workerInstance: available ? new Worker(new URL('./sqlite.worker', import.meta.url), { type: 'module' }) : undefined,
sharedWorker: !available,
sharedWorkerInstance:
!available ? new SharedWorker(new URL('./sqlite-shared.worker', import.meta.url), { type: 'module' }) : undefined,
wasmPath: available ? '/wa-sqlite/wa-sqlite.wasm' : '/wa-sqlite/wa-sqlite-async.wasm'
});
});
await rxdb.connect('wa-sqlite');
上面这段会根据浏览器能力自动选择更合适的 VFS 与 Worker 方案,优先走 OPFS 获得更好的持久化表现。
3. 读写数据
import { firstValueFrom } from 'rxjs';
// 创建
const todo = new Todo();
todo.title = '完成 RxDB 文档';
todo.createdAt = new Date();
await todo.save();
// 查询
const todos = await firstValueFrom(
Todo.find({
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
},
orderBy: [{ field: 'createdAt', sort: 'desc' }]
})
);
// 更新
todo.completed = true;
await todo.save();
// 删除
await todo.remove();
4. 订阅数据变化
用 RxJS 订阅查询结果,界面自动跟着走:
import { Subscription, switchMap } from 'rxjs';
const subscription: Subscription = rxdb
.pipe(
switchMap(() =>
Todo.find({
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
}
})
)
)
.subscribe({
next: todos => console.log('未完成的待办:', todos),
error: err => console.error('查询错误:', err)
});
// 记得在卸载时取消
subscription.unsubscribe();
如果你只想验证链路是否打通,到这里就够了。接下来就是把 Observable 绑到界面上。
接到 UI 框架
三个框架共用同一套模型和查询语义,差异只在绑定层。
React
import { RxDBProvider, useFind } from '@aiao/rxdb-react';
function App() {
return (
<RxDBProvider db={rxdb}>
<TodoList />
</RxDBProvider>
);
}
function TodoList() {
const {
value: todos,
isLoading,
isEmpty
} = useFind(Todo, {
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
},
orderBy: [{ field: 'createdAt', sort: 'desc' }]
});
if (isLoading) return <div>加载中…</div>;
if (isEmpty) return <div>暂无待办事项</div>;
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
完整接入见 React 集成 →
Vue
<script lang="ts" setup>
import { useFind } from '@aiao/rxdb-vue';
const {
value: todos,
isLoading,
isEmpty
} = useFind(Todo, {
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
},
orderBy: [{ field: 'createdAt', sort: 'desc' }]
});
</script>
<template>
<div v-if="isLoading">加载中…</div>
<div v-else-if="isEmpty">暂无待办事项</div>
<ul v-else>
<li v-for="todo in todos" :key="todo.id">{{ todo.title }}</li>
</ul>
</template>
完整接入见 Vue 集成 →
Angular
import { Component } from '@angular/core';
import { provideRxDB, useFind } from '@aiao/rxdb-angular';
@Component({
selector: 'app-todo-list',
standalone: true,
template: `
@if (isLoading()) {
<div>加载中…</div>
} @else if (isEmpty()) {
<div>暂无待办事项</div>
} @else {
<ul>
@for (todo of todos(); track todo.id) {
<li>{{ todo.title }}</li>
}
</ul>
}
`
})
export class TodoListComponent {
private resource = useFind(Todo, {
where: {
combinator: 'and',
rules: [{ field: 'completed', operator: '=', value: false }]
},
orderBy: [{ field: 'createdAt', sort: 'desc' }]
});
todos = this.resource.value;
isLoading = this.resource.isLoading;
isEmpty = this.resource.isEmpty;
}
完整接入见 Angular 集成 →
下一步
按这个顺序读,能先建立数据层心智,再决定框架和适配器怎么选: