7.2.0 • Published 2 months ago

yjr-utils v7.2.0

Weekly downloads
-
License
ISC
Repository
-
Last release
2 months ago

yjr-utils 在线文档 点击进入

下载安装

此包采用 ESModule 规范编写

npm i yjr-utils

pnpm i yjr-utils

yarn add yjr-utils

如何使用

全部加载

import * as yjrUtils from 'yjr-utils';

按需引入

import { fillZero, cloneDeep } from 'yjr-utils';

目录

1.单数补 0

单独补 0

import { fillZero } from 'yjr-utils';

fillZero('3'); // '03'

fillZero('13'); // '13'

支持分隔符来批量补 0

fillZero('1:5:9', ':'); // '01:05:09'

fillZero('13:6:29', ':'); // '13:06:29'

2.深拷贝

推荐使用 js 原生的深拷贝方法 structuredClone

/**
 * 如果担心兼容性可手动引入以下路径来充当垫片;
 * ( yjr-utils 内置了core-js )
 */
import 'core-js/actual/structured-clone';

const data = [
  {
    array: [1, 2, 3],
  },
];

const data_2 = structuredClone(data);

data === data_2; // false

或者使用 lodash 的 cloneDeep

// yjr-utils 内部直接转发 lodash 的 cloneDeep
import { cloneDeep } from 'yjr-utils';

const obj = {
  arr: [1, 2, 3],
};

const obj_2 = cloneDeep(obj);

obj === obj_2; // false

3.数组去重 ( 浅拷贝 )

基本数据类型去重

import { toSet } from 'yjr-utils';

toSet(['str', 'str', 110, 110, true, true]);
// 运行结果
['str', 110, true];

引用数据类型去重(根据某个路径)

import { toSet } from 'yjr-utils';

toSet(
  [
    { info: [180, 1] },
    { info: [177, 2] },
    { info: [178, 3] },
    { info: [178, 3] },
    { info: [171, 5] },
  ],
  'info[0]',
);

// 运行结果
[
  { info: [180, 1] },
  { info: [177, 2] },
  { info: [178, 3] },
  { info: [171, 5] },
];

4.数组排序 ( 浅拷贝 )

基本数据类型

import { doSort } from 'yjr-utils';

doSort([1, 7, 9, 5]);
// [ 1, 5, 9, 7 ]

doSort([1, 7, 9, 5], 'desc');
// [ 9, 7, 5, 1 ]

doSort(['a', 'b', 'd', 'c'], 'asc', 'english');
// [ 'a', 'b', 'c', 'd' ]

doSort(['a', 'b', 'd', 'c'], 'desc', 'english');
// [ 'd', 'c', 'b', 'a' ]

doSort(['花', '园', '宝', '宝'], 'asc', 'chinese');
// [ '宝', '宝', '花', '园' ]

doSort(['花', '园', '宝', '宝'], 'desc', 'chinese');
// [ '园', '花', '宝', '宝' ]

引用数据类型

import { doSort } from 'yjr-utils';

const data = [
  { a: { c: { d: 20 } }, b: 10 },
  { a: { c: { d: 18 } }, b: 10 },
  { a: { c: { d: 17 } }, b: 10 },
];

doSort(data, 'asc', 'number', 'a.c.d');

// 结果
[
  { a: { c: { d: 17 } }, b: 10 },
  { a: { c: { d: 18 } }, b: 10 },
  { a: { c: { d: 20 } }, b: 10 },
];

5.获得最大/小值 ( 浅拷贝 )

import { getExtreme } from 'yjr-utils';

getExtreme([1, 2, 99]); // 99

getExtreme([1, 2, 99], 'min'); // 1

// 引用数据类型使用
const data = [
  { a: { c: { d: 20 } } },
  { a: { c: { d: 18 } } },
  { a: { c: { d: 17 } } },
];

getExtreme(data, 'min', 'a.c.d'); // { a: { c: { d: 17 } } }

getExtreme(data, 'max', 'a.c.d'); // { a: { c: { d: 20 } } }

6.时间格式化

第二个参数是格式化模版,默认值是'YYYY-MM-DD HH:mm:ss'

import { timeFormat } from 'yjr-utils';

timeFormat('1999-05-12');
// '1999-05-12 08:00:00'

timeFormat(1662622488019, 'YYYY年MM月DD日 HH点mm分ss秒');
// '2022年09月08日 15点34分48秒'

7.获得时间差

传入两个时间,返回一个 天,时,分,秒 组成的数组

import { timeGap } from 'yjr-utils';

timeGap('2022-09-08 07:23:46', '2022-09-05 10:43:43');
// ['02','20','40','03'] 两个时间相差2天20小时40分钟3秒

timeGap(1662521026000, 1661999899000);
// ['06','00','45','26'] 两个时间相差6天0小时45分钟26秒

传入模板则直接返回格式化好的字符串

timeGap('2022-09-08 22:23:46', '2022-09-08 10:43:43', '还剩HH小时mm分钟ss秒');
// '还剩11小时40分钟03秒'

timeGap('2022-09-08 13:23:46', '2022-09-05 19:54:34', 'DD天HH时mm分ss秒');
// '02天17时29分12秒'

timeGap(1662521026000, 1661999899000, 'DD天HH时mm分ss秒');
// '06天00时45分26秒'

8.排序效仿 ( 浅拷贝 )

import { sortImitate } from 'yjr-utils';

const target = [
  { type: 'A', name: '小王' },
  { type: 'S', name: '小明' },
  { type: 'SS', name: '小红' },
];

const source = [
  { type: 'SS', name: '小强' },
  { type: 'A', name: '小刚' },
  { type: 'S', name: '小金' },
];

sortImitate(target, source, 'type');

// 结果
[
  { type: 'A', name: '小刚' },
  { type: 'S', name: '小金' },
  { type: 'SS', name: '小强' },
];

9.对象成员过滤(回调)

import { pickBy } from 'yjr-utils';

const obj = {
  a: 1,
  ac2: 2,
  a3: 3,
  ac4: 4,
};

pickBy(obj, (val) => val >= 2);
// { ac2: 2, a3: 3, ac4: 4 }

pickBy(obj, (_val, key) => key.startsWith('ac'));
// { ac2: 2, ac4: 4 }

10.对象成员过滤(回调),逆向

import { omitBy } from 'yjr-utils';

const obj = {
  a: 1,
  ac2: 2,
  a3: 3,
  ac4: 4,
};

omitBy(obj, (val) => val >= 2);
// { a: 1 }

omitBy(obj, (_val, key) => key.startsWith('ac'));
// { a: 1, a3: 3 }

11.防抖

import { debounce } from 'yjr-utils';

const func = () => console.log('resizing');

window.onresize = debounce(func, 500, {
  // 不等待第一个定时器结束,直接执行
  leading: true,
  // 如果一直被阻塞无法执行代码,则2秒内必定执行一次
  maxWait: 2000,
});

// 取消
window.onresize.cancel();

// 刷新
window.onresize.flush();

12.节流

import { throttle } from 'yjr-utils';

const func = () => console.log('resizing');

window.onscroll = throttle(func, 200, {
  // 不等待第一个定时器结束,直接执行
  leading: true,
});

// 取消
window.onscroll.cancel();

// 刷新
window.onscroll.flush();

13.数组分割

import { chunk } from 'yjr-utils';

chunk([1, 2, 3, 4], 2);
// [[1,2],[3,4]] 两个成员一组来分组

chunk([1, 2, 3, 4], 3);
// [[1,2,3],[4]] 三个成员一组来分组

const data = [
  { a: 1, b: 1 },
  { a: 2, b: 2 },
  { a: 3, b: 3 },
  { a: 4, b: 4 },
];

chunk(data, 2);

// 结果
[
  [
    { a: 1, b: 1 },
    { a: 2, b: 2 },
  ],
  [
    { a: 3, b: 3 },
    { a: 4, b: 4 },
  ],
];

14.获得一个随机数

import { random } from 'yjr-utils';

random(-10, 20); // -2

random(5, 10); // 7

random(1.2, 5.2); // 3.4508875522514773

// 不返回整数
random(0, 4, true); // 3.154170094134428

random(0, 4); // 3

15. 文字超出省略

支持 空格-汉字-数字-字母-特殊字符-字体图标-表情 等 7 种字符省略处理

import { textEllipsis } from 'yjr-utils';

textEllipsis('Ab&_12看看 👀🆕😊❤️', 10);
// 'Ab&_12看看 👀...'

textEllipsis('🉑️23', 3);
// '🉑️2...'   某些非常特殊的字体图标会占用2个位置

textEllipsis('❤️ab', 3);
// '❤️a...'    某些非常特殊的字体图标会占用2个位置

textEllipsis('abcdef', 4, true);
// 'a...'  开启严格模式,'...'也会消费你传入的长度

16.剩余时间

timeGap 的简化版本,直接传入一个差值时间戳

import { remainTime } from 'yjr-utils';

remainTime(7081940);
// ['00', '01', '58', '02']

remainTime(7081940, '还剩DD天HH小时mm分钟ss秒');
// '还剩00天01小时58分钟02秒'

17.监听元素是否可见

<div id="box"></div>
import { watchDomIsVisible } from 'yjr-utils';

const dom = document.getElementById('box');

const handler = (e) => {
  console.log(e ? '元素可见' : '元素不可见');
};

const { watch, unwatch } = watchDomIsVisible(dom, handler);

watch(); // 开始监听 元素露出50%算作可见,反之不可见

unwatch(); // 停止监听

还可以设置阈值

// 阈值默认为0.5 可传0-1
const { watch, unwatch } = watchDomIsVisible(dom, handler, 0.3);

watch(); // 开始监听 元素露出30%算作可见,反之不可见

unwatch(); // 停止监听

18.获取数据类型

import { getType } from 'yjr-utils';

getType([1, 2, 3]);
// 'array'

getType({ a: 10 });
// 'object'

getType(null);
// 'null'

19.合并数据

import { merge } from 'yjr-utils';

const base = {
  a: [{ b: 2 }, { d: 4 }],
};

const other = {
  a: [{ c: 3 }, { e: 5 }],
};

merge(base, other);

// 结果
{
  a: [
    { b: 2, c: 3 },
    { d: 4, e: 5 },
  ];
}

20.判断两个变量是否相等

import { isEqual } from 'yjr-utils';

const base = {
  a: [1, 2, 3],
};

const other = {
  a: [1, 2, 3],
};

isEqual(base, other); // true 结构完全相同

base === other; // false 内存地址不一样

21.使用未发布的数组 Api

如果你想使用 findLast,findLastIndex,with,toSpliced,toReversed

这些已经在 ESNext.d.ts 中出现但未发布的数组方法,导入该模块即可

import 'yjr-utils/src/arrayPolyfills.js';

如果是 ts 项目,则还需要在你项目中的 d.ts 文件中引入声明文件

/// <reference types="yjr-utils/src/arrayPolyfills.d.ts" />

导入以上文件后就可以在你的项目中使用这些 Api 了

[1, 2, 3].with(1, 90); // [1,90,3]

[1, 2, 3].toReversed(); // [3,2,1]

[1, 2, 3].toSpliced(1, 0, 2, 3); // [1,2,3,2,3]

22.拉平嵌套对象 ( 浅拷贝 )

import { flatObj } from 'yjr-utils';

const nest = [
  {
    id: 1,
    pid: 0,
    children: [
      {
        id: 2,
        pid: 1,
        children: [
          {
            id: 3,
            pid: 2,
          },
        ],
      },
    ],
  },
];

flatObj(nest);

// 结果
[
  {
    id: 1,
    pid: 0,
  },
  {
    id: 2,
    pid: 1,
  },
  {
    id: 3,
    pid: 2,
  },
];
const nest2 = [
  {
    route: 'home',
    pRoute: '',
    children: [
      {
        route: 'home/main',
        pRoute: 'home',
        children: [
          {
            route: 'home/main/index',
            pRoute: 'home/main',
          },
        ],
      },
    ],
  },
];

flatObj(nest2);

// 结果

[
  {
    route: 'home',
    pRoute: '',
  },
  {
    route: 'home/main',
    pRoute: 'home',
  },
  {
    route: 'home/main/index',
    pRoute: 'home/main',
  },
];

23.使平级对象嵌套 ( 浅拷贝 )

import { nestedObj } from 'yjr-utils';

const flat = [
  {
    id: 1,
    pid: 0,
  },
  {
    id: 2,
    pid: 1,
  },
  {
    id: 3,
    pid: 2,
  },
];

nestedObj(flat, 'id', 'pid');

// 结果
[
  {
    id: 1,
    pid: 0,
    children: [
      {
        id: 2,
        pid: 1,
        children: [
          {
            id: 3,
            pid: 2,
          },
        ],
      },
    ],
  },
];
const flat2 = [
  {
    route: 'home',
    pRoute: '',
  },
  {
    route: 'home/main',
    pRoute: 'home',
  },
  {
    route: 'home/main/index',
    pRoute: 'home/main',
  },
];

nestedObj(flat, 'route', 'pRoute');

// 结果
[
  {
    route: 'home',
    pRoute: '',
    children: [
      {
        route: 'home/main',
        pRoute: 'home',
        children: [
          {
            route: 'home/main/index',
            pRoute: 'home/main',
          },
        ],
      },
    ],
  },
];

24.获取滚动条宽度

import { getScrollBarWidth } from 'yjr-utils';

getScrollBarWidth(); // 17

25.对象成员过滤

import { pick, omit } from 'yjr-utils';

const object = { a: 1, b: '2', c: 3 };

omit(object, ['a', 'c']);
// { 'b': '2' }

pick(object, ['a', 'c']);
// { 'a': 1, 'c': 3 }

26.对象转查询字符串

值为 null 或 undefined 会被自动过滤掉

import { queryString } from 'yjr-utils';

const obj = {
  number: 1,
  null: null,
  undefined: undefined,
  string: 'str',
  bool: true,
};

queryString(obj);
// number=1&string=str&bool=true

27.获取地址栏参数

import { getURLParameters } from 'yjr-utils';

window.location.href =
  'https://www.npmjs.com/package/yjr-utils?activeTab=versions';

getURLParameters();
// { activeTab : 'versions' };

28.货币格式化

import { currencyFormat } from 'yjr-utils';

currencyFormat(123456); // '123,456'

currencyFormat(1234567); // '1,234,567'

currencyFormat(123456.86); // '123,456.86'

29.浮点型精准计算

import { preciseCalculation } from 'yjr-utils';

// 未处理前 0.1 + 0.2 = 0.30000000000000004
preciseCalculation(0.1, 0.2, '+'); // 0.3;

// 未处理前 0.8 - 0.1 = 0.7000000000000001
preciseCalculation(0.8, 0.1, '-'); // 0.7;

// 未处理前 0.1 * 0.2 = 0.020000000000000004
preciseCalculation(0.1, 0.2, '*'); // 0.02;

// 未处理前 0.6 / 0.2 = 2.9999999999999996
preciseCalculation(0.6, 0.2, '/'); // 3;

30.监听页面可视状态

import { pageIsVisible } from 'yjr-utils';

const handler = (e) => {
  console.log(e === 'visible' ? '页面可见' : '页面不可见');
};

const { watch, unwatch } = pageIsVisible(handler);

watch(); // 开始监听

unwatch(); // 停止监听

31.对比两组数据间的差异

import { jsDiff } from 'yjr-utils';

const obj1 = {
  a: 100,
  b: 50,
  c: 6,
};

const obj2 = {
  a: 101,
  b: 50,
  d: 99,
};

jsDiff(obj1, obj2);

// 结果
[
  {
    path: 'a',
    desc: '修改',
    _old: 100,
    _new: 101,
  },
  {
    path: 'd',
    desc: '新增',
    _new: 99,
    _old: undefined,
  },
  {
    path: 'c',
    desc: '删除',
    _old: 6,
    _new: undefined,
  },
];

32.是否是移动设备/是否是 IOS

import { isMobile, isIOS } from 'yjr-utils';

isMobile(); // true || false

isIOS(); // true || false

33. H5 应用适配 IOS 键盘

import { fitKeyboardInIOS } from 'yjr-utils';

/**
 * 如果你的H5应用被以下问题所困扰,直接引入此方法即可
 * 1.ios键盘弹起导致导航栏被顶走
 * 2.ios键盘切换输入法或者切到表情面板导致页面底部被盖住
 */

// 在主应用节点第一次渲染完毕后获取,然后传给fitKeyboardInIOS即可
<div id="root">
  <div id="App">your node</div>
</div>;

const App = document.getElementById('App');

fitKeyboardInIOS(App);

动画效果

仅 2.8.0 版本及以上支持,动画效果构建产物来自 Animate.css

yjrUtils 自带以下 9 种动画效果

1.fadeIn
2.fadeInLeft
3.fadeInRight
4.fadeInUp
5.flipInX
6.flipInY
7.rotateInDownLeft
8.rotateInDownRight
9.zoomIn

动画效果为可选,如需使用,引入该文件即可

import 'yjr-utils/yjrani.css';

1.通过类名使用

yjranimated 是固定前缀 动画效果为 yjr + 具体动画名

<div class="yjranimated yjrzoomIn">An animated element</div>

通过添加 yjrdelay 前缀来延迟动画 比如这里延迟 2 秒触发

<div class="yjranimated yjrzoomIn yjrdelay-2s">An animated element</div>

类似的还有控制速度和重复次数

<div class="yjranimated yjrzoomIn yjrfaster yjrrepeat-3">
  An animated element
</div>

2.通过 @keyframes 方式使用

只需填入动画名即可使用动画效果

.className {
  animation: zoomIn 0.5s ease 0s infinite;
}

3.自定义 CSS 变量

局部变量 改变 zoomIn 这个动画持续时间为 2s

.yjranimated.yjrzoomIn {
  --animate-duration: 2s;
}

全局变量 所有动画效果都是延迟 900 毫秒且持续时间为 800 毫秒

:root {
  --animate-duration: 800ms;
  --animate-delay: 0.9s;
}

4.使用注意

为了确保动画不影响你原有的样式,建议每个动画元素都加上这句 css 代码

.demo {
  animation-fill-mode: both;
}
7.2.0

2 months ago

7.1.0

3 months ago

7.0.1

5 months ago

5.5.1

11 months ago

5.5.0

11 months ago

5.3.1

12 months ago

6.1.0

10 months ago

6.1.1

10 months ago

5.6.1

10 months ago

5.6.0

10 months ago

5.4.0

11 months ago

6.0.1

10 months ago

6.0.0

10 months ago

6.2.1

10 months ago

6.2.0

10 months ago

6.2.2

9 months ago

7.0.0

9 months ago

5.5.9

10 months ago

5.5.8

11 months ago

5.5.7

11 months ago

5.5.6

11 months ago

5.5.5

11 months ago

5.5.4

11 months ago

5.5.3

11 months ago

5.5.2

11 months ago

5.3.0

12 months ago

5.1.1

12 months ago

5.1.0

12 months ago

3.4.0

1 year ago

3.2.1

1 year ago

3.2.0

1 year ago

3.4.4

1 year ago

3.4.3

1 year ago

3.4.2

1 year ago

3.4.1

1 year ago

4.0.1

1 year ago

4.0.0

1 year ago

5.2.2

12 months ago

5.2.1

12 months ago

5.2.0

12 months ago

5.0.0

12 months ago

3.4.5

1 year ago

3.3.0

1 year ago

4.1.0

1 year ago

4.1.1

1 year ago

3.1.1

1 year ago

3.0.2

2 years ago

3.1.0

1 year ago

3.0.1

2 years ago

3.0.0

2 years ago

2.15.0

2 years ago

2.15.1

2 years ago

2.13.0

2 years ago

2.14.0

2 years ago

2.13.1

2 years ago

2.12.3

2 years ago

2.12.2

2 years ago

2.12.1

2 years ago

2.12.0

2 years ago

2.11.4

2 years ago

2.11.3

2 years ago

2.11.2

2 years ago

2.11.1

2 years ago

2.11.0

2 years ago

2.10.1

2 years ago

2.10.0

2 years ago

2.9.0

2 years ago

2.8.1

2 years ago

2.8.0

2 years ago

2.7.1

2 years ago

2.7.0

2 years ago

2.6.1

2 years ago

2.6.0

2 years ago

2.5.0

2 years ago

2.4.0

2 years ago

2.3.0

2 years ago

2.2.1

2 years ago

2.2.0

2 years ago

2.1.0

2 years ago

2.0.0

2 years ago

1.0.3

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago