Skip to content

默认入口

ts
import { /* ... */ } from '@tripo3d/utils';

默认入口聚合了浏览器侧的通用工具:设备检测、Promise 工具、跳转/下载、文件名/MIME、文件读取、localStorage 包装

设备检测

isMobileDevice

函数签名说明
isMobileDevice(ua: string | null) => boolean识别 UA 是否为移动端浏览器(android / webos / iphone / ipod / blackberry / iemobile / opera mini)
ts
import { isMobileDevice } from '@tripo3d/utils';

if (isMobileDevice(navigator.userAgent)) {
  // 走移动端路径
}

为什么要传参

显式传入 UA 而不是内部读 navigator,便于 SSR 场景下从请求 header 注入。空值返回 false,不会抛错。

Promise 工具

sleep

函数签名说明
sleep(ms: number) => Promise<void>延迟 N 毫秒解决 Promise,常用于节流、动画衔接
ts
import { sleep } from '@tripo3d/utils';

await sleep(300);
console.log('300ms 后执行');

pf(promise factory)

外部解构 resolve / reject 的 Promise 工厂——适合把"等用户操作完成"封成 Promise(如等待弹窗确认、等待 OAuth 回调)。

函数签名说明
pf<T, U = any>() => { promise: Promise<T>, resolve: (v) => void, reject: (e) => void }返回 promise 与外部可调用的 resolve/reject
ts
import { pf } from '@tripo3d/utils';

function waitForLogin() {
  const { promise, resolve } = pf<string>();
  // 在某个事件回调里调 resolve('token')
  document.addEventListener('login-done', e => resolve(e.detail), { once: true });
  return promise;
}

const token = await waitForLogin();

跳转 / 下载

jumpdownload 都是基于动态 <a> 元素 + .click() 实现,无需手动管理 DOM。

函数签名说明
jump(url: string, blank = true) => void导航到 URL,默认在新标签页打开。blank=false 替换当前页
download(url: string, name?: string) => void触发浏览器下载。name 设置文件名(需同源或服务端配置 Content-Disposition)
ts
import { download, jump } from '@tripo3d/utils';

jump('https://tripo3d.ai');                      // 新标签页打开
jump('/dashboard', false);                       // 当前页跳转

download('https://example.com/file.zip');        // 下载,文件名由响应头决定
download('https://example.com/file.zip', 'my.zip'); // 下载并重命名(需同源)

跨源下载文件名

浏览器只在同源或服务端 Content-Disposition 配合时才会接受 download 属性的文件名。跨源 CDN 上的文件,用户最终拿到的可能是原始文件名。

文件名 / MIME

getSuffix

函数签名说明
getSuffix(file: File | string) => string | undefined提取文件扩展名(小写)。传 File 对象时,扩展名缺失会回退到 MIME 后段
ts
import { getSuffix } from '@tripo3d/utils';

getSuffix('https://cdn.example.com/x/a.PNG');    // 'png'
getSuffix(new File([], 'photo.JPEG'));           // 'jpeg'
getSuffix(new File([], 'no-extension', { type: 'image/webp' })); // 'webp'(回退到 MIME)

readFileAsDataURL

函数签名说明
readFileAsDataURL(file: File) => Promise<string>FileReader 包装,把 File 读成 base64 data URL。失败时 reject
ts
import { readFileAsDataURL } from '@tripo3d/utils';

const dataUrl = await readFileAsDataURL(file); // 'data:image/png;base64,...'
img.src = dataUrl;

localStorage 包装

带 JSON 序列化的 localStorage仅在浏览器环境可用,SSR 时直接调用会抛 localStorage is not defined

函数签名说明
getStorage<T>(key: string) => T | nullJSON.parse 失败或 key 不存在返回 null。不会抛错
setStorage(key: string, value: unknown) => voidJSON.stringify 后写入。值过大会触发 QuotaExceededError(未捕获)
removeStorage(key: string) => void删除 key
ts
import { getStorage, removeStorage, setStorage } from '@tripo3d/utils';

interface UserPref {
  theme: 'light' | 'dark';
  lang: string;
}

setStorage('user-pref', { theme: 'dark', lang: 'zh-CN' });
const pref = getStorage<UserPref>('user-pref');
if (pref) console.log(pref.theme);

removeStorage('user-pref');

下一步

  • Date — dayjs 包装与时区
  • Resource — AWS S3 上传
  • Playground — 工具函数交互测试 + Tripo 图标集浏览

基于 MIT 协议发布(内部使用)