跳转到内容

读写实战

import { useMutation, useQuery } from '@iostore/vue';
const todos = useQuery({
key: ['todos'],
queryFn: ({ signal }) => $fetch('/api/todos', { signal }),
});
const createTodo = useMutation({
mutationFn: (title: string) =>
$fetch('/api/todos', { method: 'POST', body: { title } }),
onSuccess: async () => {
await todos.invalidate();
},
});
import { io } from '@iostore/store';
import { useIO, useQuery } from '@iostore/vue';
const localState = io({ tab: 'all', page: 1 });
const local = useIO(localState);
const q = useQuery({
key: ['todos', local.value.tab, local.value.page],
queryFn: ({ signal }) =>
fetch('/api/todos', { signal }).then((r) => r.json()),
});
  • 远端真值由 Query 管理,本地交互状态由 useIO(Svelte 对应 store 适配)管理。
  • 本地状态驱动查询时,参数必须完整进入 key
  • 输入高频场景建议结合 batch 与调度策略。
  • 对网络抖动使用有限重试;对业务错误直接暴露并停止重试。
  • 有乐观更新时,在 onMutate 保存快照,在 onError 回滚。
  • 取消(AbortError)不应写入错误看板。
  1. key 只放可序列化数据,且顺序稳定。
  2. 把筛选条件、租户、分页参数全部纳入 key。
  3. 不要在 key 中放函数、类实例、DOM 节点。
// 错误:tenantId 未进入 key
key: ['users'];
key: ['users', tenantId];
// 错误:直接本地拼补丁,长期会偏离服务端
onSuccess: (item) => {
cache.push(item);
};
onSuccess: async () => {
await todos.invalidate();
};