@fallen-zero/use
fallen-zero Api
2,609
2
| Install | |
|---|---|
npm install @fallen-zero/use |
|
| Latest Version: | 1.3.5 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Feb 5, 2026 |
| Links: | GitHub · npm |
Maintainer: fallen-zero
Fallen-Zero Use
Vue 3 composition hooks and browser utilities used by Fallen Zero projects.
Install
# with npm
npm i @fallen-zero/use
# with yarn
yarn add @fallen-zero/use
# with pnpm
pnpm add @fallen-zero/use
Usage
import { useRequest, useVisible } from '@fallen-zero/use';
功能
请求与列表
| API | 说明 |
|---|---|
useRequest |
包装 Promise 请求,返回 data、error、loading、run、setParams、reset、cancel。 |
useRequestImmediate |
立即执行一次请求并返回响应式状态。 |
useApiList |
分页列表加载,提供 list、total、loading、finished、onLoad、reset。 |
Vue Hooks
| API | 说明 |
|---|---|
useVisible |
管理弹窗、抽屉等布尔显示状态。 |
useDebounceRef |
创建带防抖写入的 ref。 |
UseDefer |
按动画帧延迟渲染大量内容。 |
useCompRef / useCompRefs |
为组件实例创建带类型的 ref。 |
useIntervalDate |
每秒更新当前日期、时间和星期。 |
useCountdown |
根据结束时间生成 HH:mm:ss 倒计时。 |
useTimeDown |
基于 localStorage 的验证码/冷却倒计时。 |
useTheme |
管理 light / dark 主题并写入 data-theme。 |
useResize |
复用单个 ResizeObserver 监听元素尺寸变化。 |
useRem |
根据设计稿宽度设置根元素 font-size。 |
useLoopExec |
按固定间隔循环执行同步或异步任务。 |
useAnimation |
使用 requestAnimationFrame 生成补间动画值。 |
useStore / StorageEnum |
统一读写 sessionStorage、localStorage 和 Cookie。 |
工具函数
| API | 说明 |
|---|---|
dateFormat / DATE_FORMAT |
常用日期格式化。 |
decimalPlaces / toFixed / toPrecision / sum |
数字精度和求和工具。 |
strToArray / arrayToStr / parseJSON |
字符串、数组和 JSON 转换。 |
encryptName / encrypt |
姓名、手机号、身份证、银行卡、邮箱脱敏。 |
getSystemAgent / UserAgent |
判断 iOS、Android、微信、钉钉等运行环境。 |
FontSize |
根据屏幕宽度计算适配后的字体大小。 |
useFormData |
将对象转换为 FormData。 |
ImageCompression、base64ToBlob、base64ToFile、fileToBinary |
图片压缩和文件转换。 |
getFileExt / getFileSize / getFileName / useFullUrl |
文件名、大小和 URL 处理。 |
numToCapital / toChineseAmount |
数字转中文或人民币大写。 |
getIdCardInfo / getAgeByIdCard / getSexByIdCard |
根据身份证号获取年龄和性别。 |
isEmptyValue / isImage / isVideo |
空值、图片路径和视频路径判断。 |
validatePhone / validateTel / validatePhoneAndTel |
手机号和电话号码校验。 |
validatePhoneAndTelMD / isVehicleNumber |
脱敏号码和车牌号校验。 |
anyIsEqual / arrayIsEqual / objectIsEqual / isAllEqual |
深比较数组、对象和值。 |
convertColor |
将 hex/rgb/rgba 转为带透明度的 rgba。 |
createField / fommaterIndex |
生成展示字段配置。 |
Loader |
动态挂载和卸载 Vue 组件。 |
createTagMsg |
基于 BroadcastChannel 的跨标签页消息。 |
preformChunk / browserPerformChunk / timeoutPerformChunk |
分片执行大批量任务,避免长时间阻塞主线程。 |
isFunction、isObject、isArray 等 |
常用类型判断函数。 |
使用案例
请求与列表
import {
CreateRequest,
useApiList,
useRequest,
useRequestImmediate,
} from '@fallen-zero/use';
const getUser = (id: number) => Promise.resolve({ id, name: 'Zero' });
const request = useRequest(getUser, [1], {
immediate: false,
success: (user) => console.log(user.name),
});
await request.run();
await request.setParams([2]);
await request.reset();
request.cancel();
const appRequest = new CreateRequest({
checkStatus: (res) => res.code === 0,
showError: (err) => console.error(err),
});
const userRequest = appRequest.requestApi(
() => Promise.resolve({ code: 0, data: [] }),
[],
{ immediate: false },
);
await userRequest.run();
const immediate = await useRequestImmediate(getUser, 1);
console.log(immediate.data.value);
const listApi = ({ page = 1, limit = 10 }) =>
Promise.resolve({
list: Array.from({ length: limit }, (_, index) => page * limit + index),
total: 100,
});
const { list, total, loading, finished, onLoad, reset, setParams } = useApiList(
listApi,
{ page: 1, limit: 20 },
{ immediate: false },
);
await onLoad();
await setParams({ limit: 30 });
await reset();
console.log(list.value, total.value, loading.value, finished.value);
Vue Hooks
import {
StorageEnum,
UseDefer,
useAnimation,
useCompRef,
useCompRefs,
useCountdown,
useDebounceRef,
useIntervalDate,
useLoopExec,
useRem,
useResize,
useStore,
useTheme,
useTimeDown,
useVisible,
} from '@fallen-zero/use';
import UserCard from './UserCard.vue';
const modal = useVisible();
modal.open();
modal.toggle();
modal.close();
console.log(modal.visible.value);
const keyword = useDebounceRef('', 300);
keyword.value = 'search text';
const defer = new UseDefer(60);
const showRow = defer.defer(20);
defer.setMaxCount(120);
console.log(showRow, defer.getMaxCount());
const userCardRef = useCompRef(UserCard);
const userCardRefs = useCompRefs(UserCard);
const { currDate } = useIntervalDate();
console.log(currDate.date, currDate.time, currDate.week);
const countdown = useCountdown('2026-12-31 23:59:59');
console.log(countdown.currentTime.value, countdown.isEnd.value);
countdown.clearTimer();
countdown.startTimer();
const verifyCode = useTimeDown('login-code', 60, () => console.log('done'));
verifyCode.start();
console.log(verifyCode.time.value, verifyCode.finish.value);
verifyCode.stop();
const { theme, toggleTheme } = useTheme('light');
toggleTheme('dark');
console.log(theme.value);
const { observe, unobserve } = useResize();
const element = document.querySelector('#panel');
observe(element, () => console.log('resized'));
unobserve(element);
const { changeRem } = useRem({ designWidth: 1920, size: 192 });
changeRem({ rootWidth: 1440 });
const loop = useLoopExec(() => console.log(Date.now()), 2000);
loop.loop();
loop.cancel();
useAnimation(300, 0, 100, (value) => {
document.body.style.opacity = String(value / 100);
});
const store = useStore('demo');
store.set('token', 'abc', { storage: StorageEnum.LOCAL, expire: 3600 });
console.log(store.get<string>('token', StorageEnum.LOCAL));
store.remove('token', StorageEnum.LOCAL);
日期、数字与字符串
import {
DATE_FORMAT,
arrayToStr,
dateFormat,
decimalPlaces,
fommaterIndex,
numToCapital,
parseJSON,
strToArray,
sum,
toChineseAmount,
toFixed,
toPrecision,
} from '@fallen-zero/use';
dateFormat(new Date(), DATE_FORMAT['DATETIMES-']);
decimalPlaces(3.1415);
toFixed(3.1415, 2);
toPrecision(3.1415, 2);
sum(1, 2, 3);
strToArray('a,b,c');
arrayToStr(['a', 'b', 'c']);
parseJSON('{"name":"Zero"}', { name: '' });
numToCapital(1203);
toChineseAmount(1203.45);
fommaterIndex(8);
文件与浏览器工具
import {
FontSize,
ImageCompression,
UserAgent,
base64ToBlob,
base64ToFile,
convertColor,
createTagMsg,
fileToBinary,
getFileExt,
getFileName,
getFileSize,
getSystemAgent,
useFormData,
useFullUrl,
} from '@fallen-zero/use';
declare const file: File;
declare const base64: string;
const formData = useFormData({ name: 'Zero', tags: ['vue'] });
new ImageCompression({
file,
quality: 0.8,
success: (base64) => console.log(base64),
});
const blob = base64ToBlob(base64, 'image/png');
const imageFile = base64ToFile(base64, 'avatar.png', 'image/png');
const bytes = await fileToBinary(imageFile);
getFileExt('avatar.png');
getFileSize(file);
getFileName('/upload/avatar.png');
const fullUrl = useFullUrl('https://cdn.example.com');
fullUrl('~/avatar.png');
FontSize(16);
getSystemAgent(UserAgent.微信);
convertColor('#1677ff', 0.5);
const tagMsg = createTagMsg('app');
const stopListen = tagMsg.listenMsg((msg) => console.log(msg.type));
tagMsg.sendMsg('refresh', { id: 1 });
stopListen();
校验、比较与类型判断
import {
anyIsEqual,
arrayIsEqual,
encrypt,
encryptName,
getAgeByIdCard,
getIdCardInfo,
getSexByIdCard,
isAllEqual,
isArray,
isBoolean,
isDate,
isEmptyValue,
isFile,
isFunction,
isImage,
isNull,
isNumber,
isObject,
isPromise,
isRegExp,
isString,
isUndefined,
isVehicleNumber,
isVideo,
objectIsEqual,
validatePhone,
validatePhoneAndTel,
validatePhoneAndTelMD,
validateTel,
} from '@fallen-zero/use';
declare const file: File;
encryptName('张三');
encrypt('phone', '13800138000');
getSexByIdCard('110101199001011234');
getAgeByIdCard('110101199001011234');
getIdCardInfo('110101199001011234');
isEmptyValue('');
isImage('avatar.webp');
isVideo('demo.mp4');
isVehicleNumber('浙A12345');
validatePhone('13800138000');
validateTel('0571-12345678');
validatePhoneAndTel('0571-12345678');
validatePhoneAndTelMD('138****8000');
isAllEqual({ a: 1 }, { a: 1 });
arrayIsEqual([1, 2], [2, 1], true);
objectIsEqual({ a: 1 }, { a: 1 });
anyIsEqual([{ a: 1 }], [{ a: 1 }]);
isFunction(() => {});
isObject({});
isArray([]);
isString('zero');
isNumber(1);
isBoolean(false);
isDate(new Date());
isRegExp(/zero/);
isUndefined(undefined);
isNull(null);
isPromise(Promise.resolve());
isFile(file);
字段、加载器与分片任务
import {
Loader,
browserPerformChunk,
createField,
preformChunk,
timeoutPerformChunk,
} from '@fallen-zero/use';
import Toast from './Toast.vue';
const fields = createField(
[
{ label: '姓名', key: 'name' },
{ label: '年龄', key: 'age', visible: (age) => age > 0 },
],
{ name: 'Zero', age: 18 },
);
const loader = new Loader(Toast);
await loader.show();
loader.hide();
browserPerformChunk([1, 2, 3], (item) => console.log(item));
timeoutPerformChunk(1000, (_, index) => console.log(index), 16, 0);
preformChunk(
[1, 2, 3],
(item) => console.log(item),
(task) => task(() => true),
);
console.log(fields);
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.3.5 | ^3.0.0 | MIT | |
| 1.3.4 | ^3.0.0 | MIT | |
| 1.3.3 | ^3.0.0 | MIT | |
| 1.3.2 | ^3.0.0 | MIT | |
| 1.3.1 | ^3.0.0 | MIT | |
| 1.3.0 | ^3.0.0 | MIT | |
| 1.2.14 | ^3.0.0 | MIT | |
| 1.2.13 | ^3.0.0 | MIT | |
| 1.2.12 | ^3.0.0 | MIT | |
| 1.2.11 | ^3.0.0 | MIT | |
| 1.2.10 | ^3.0.0 | MIT | |
| 1.2.9 | ^3.0.0 | MIT | |
| 1.2.8 | ^3.0.0 | MIT | |
| 1.2.7 | ^3.0.0 | MIT | |
| 1.2.6 | ^3.0.0 | MIT | |
| 1.2.5 | ^3.0.0 | MIT | |
| 1.2.4 | ^3.0.0 | MIT | |
| 1.2.3 | ^3.0.0 | MIT | |
| 1.2.2 | ^3.0.0 | MIT | |
| 1.2.1 | ^3.0.0 | MIT | |
| 1.2.0 | ^3.0.0 | MIT | |
| 1.1.9 | ^3.0.0 | MIT | |
| 1.1.8 | ^3.0.0 | MIT | |
| 1.1.7 | ^3.0.0 | MIT | |
| 1.1.6 | ^3.0.0 | MIT | |
| 1.1.5 | ^3.0.0 | MIT | |
| 1.1.4 | ^3.0.0 | MIT | |
| 1.1.3 | ^3.0.0 | MIT | |
| 1.1.2 | ^3.0.0 | MIT | |
| 1.1.1 | ^3.0.0 | MIT |
Showing the latest 30 of 40. See every release on npm