Skip to content

Vue / React 适配层 ​

两套适配层共享同一 hooks 语义,返回结构几乎一致;迁移成本为零。源码入口:src/vue/index.ts、src/react/index.ts(v0.2.0 逐项核对)。

usePartakeUpload ​

ts
usePartakeUpload(opts: ManagerOptions): UsePartakeUpload

ManagerOptions 见 core 文档:controlBase 必填,其余全可选(默认值见配置表)。

⚠️ hook 语义:opts 仅在首次调用生效(Vue 侧 setup 固化;React 侧 useRef 惰性初始化)——core 无配置热更语义,后续渲染传入的新 opts 被忽略。

返回结构 ​

ts
type UsePartakeUpload = {
  // 响应式状态
  tasks: Task[];                     // vue: shallowReactive(重建驱动渲染); react: version memo 快照
  stats: { total: number; uploading: number; completed: number; failed: number; error: number };
                                     // vue: computed; react: version memo。failed 口径含 quarantined
  version: number;                   // ⚠️ 仅 react 返回(useSyncExternalStore 快照值;vue 无需暴露)

  // 命令式控制(vue: 直接绑定 manager 方法; react: 构造时绑定,引用稳定)
  addFiles(files: File[]): Task[];
  start(taskId?: string): void;
  startAll(): void;
  abort(taskId: string): Promise<void>;
  abortAll(): Promise<void>;
  pause(taskId: string): Promise<void>;
  pauseAll(): Promise<void>;
  resume(taskId: string): void;
  resumeAll(): void;
  removeTask(taskId: string): Promise<void>;
  retryTask(taskId: string): void;
  getTask(taskId: string): Task | undefined;
  downloadUrl(fileId: string): Promise<{ url: string; expiresAt: number }>;
};

方法语义与 PartakeUploadManager 完全一致。

downloadUrl ​

completed 态取下载预签名地址;quarantined 后端返回 409 → 抛 Error(非 PartakeError):

ts
const { url, expiresAt } = await downloadUrl(task.fileId!);
location.assign(url);   // 或 <a :href="url"> 打开下载

Vue 3 ​

ts
import { usePartakeUpload } from '@pidaqing/uploader/vue';

实现要点(v0.2 批次 B 修正):manager 突变的是原始 Task 引用,绕过 reactive proxy 的 set trap——适配层以 shallowReactive 数组 + 订阅重建(splice 清空再 push,元素保持原始引用)驱动渲染;进度类高频更新经 manager 100ms 合并,恰好是渲染节流。

ts
const { tasks, stats, addFiles, pause, resume, downloadUrl } = usePartakeUpload({
  controlBase: '/api/partake',
  speedLimit: 1024 * 1024,        // 1MB/s
  urlWaterline: 'auto',
});

addFiles([file]);                 // hash → 秒传探测 → 分片 PUT → complete(自动启动)

watch(() => stats.value.completed, (n) => console.log('完成数', n));

stats 是 computed——模板直接使用即可;tasks 变更即渲染(含 paused 徽标所需字段)。

React 18+ ​

ts
import { usePartakeUpload } from '@pidaqing/uploader/react';

实现要点:基于 useSyncExternalStore 订阅 manager.version(任意 Task 突变/增删递增)——React 无 Proxy 细粒度追踪,tasks/stats 按 version memo;命令式方法引用稳定,effect 依赖数组安全;第三参数快照 = SSR/hydration 就绪(Next.js 开箱即用)。

tsx
function App() {
  const { tasks, stats, version, addFiles, pause, resume } = usePartakeUpload({
    controlBase: '/api/partake',
  });

  useEffect(() => {
    console.log('版本变更', version);   // version 变化即任务集变化
  }, [version]);

  return (
    <div>
      <p>完成 {stats.completed} / 总数 {stats.total}</p>
      <button onClick={() => addFiles(pickFiles())}>添加</button>
      <ul>
        {tasks.map((t) => (
          <li key={t.id}>
            {t.fileName} — {Math.round(t.progress * 100)}%{' '}
            {t.paused && <button onClick={() => resume(t.id)}>继续</button>}
            <button onClick={() => pause(t.id)}>暂停</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

两适配层差异速查 ​

维度VueReact
响应式机制shallowReactive + 订阅重建useSyncExternalStore + version memo
version不返回返回
stats 类型ComputedRef<Stats>Stats(普通对象)
渲染触发数组 length/重建version 快照变化
SSR—第三参数 getSnapshot(hydrate 安全)

MIT Licensed · partake 生态