JS工具

数组添加优雅写法

1
2
3
(todo) => {
setTodoList((todoList) => [...todoList, todo]);
}; //react hooks

金额格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
* formatMoney(s,type)
* 功能:金额按千位逗号分隔,负号用'-'号
* 参数:s,需要格式化的金额数值.
* 参数:type,判断格式化后的金额是否需要小数位.
* 返回:返回格式化后的数值字符串.
*/
function formatMoney(s, type) {
var result = s;
if (s < 0) s = 0 - s;
if (/[^0-9\.]/.test(s)) return "0.00";
if (s == null || s == "null" || s == "") return "0.00";
if (type > 0) s = new Number(s).toFixed(type);
s = s.toString().replace(/^(\d*)$/, "$1.");
s = (s + "00").replace(/(\d*\.\d\d)\d*/, "$1");
s = s.replace(".", ",");
var re = /(\d)(\d{3},)/;
while (re.test(s)) s = s.replace(re, "$1,$2");
s = s.replace(/,(\d\d)$/, ".$1");
if (type == 0) {
var a = s.split(".");
if (a[1] == "00") {
s = a[0];
}
}
if (result < 0) result = "-" + s;
else result = s;
return result;
}

手机号固话正则校验

支持手机号码,3-4 位区号,7-8 位直播号码,1-4 位分机号,支持支持手机号码,3-4 位区号,7-8 位直播号码,1-4 位分机号

1
/(^(1[3|4|5|7|8|9][0-9]\d{8})$|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)/g;

JS 去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//filter去重
this.expertList = res.filter((item,index) =>{
return res.findIndex(i =>item.userId == i.userId) == index
})

//reduce去重
const hash = {};
const newArray = arr.reduce((item, next)=>{
hash[next.key] ? '' : hash[next.key] = true && item.push(next);
return item;
},[])

//new Set去重
unique(arr) {
const res = new Map();
return arr.filter((arr) => !res.has(arr.id) && res.set(arr.id, 1))
}

多组对象转化数组(reduce)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
let obj = {
normal: {
//标准值
timeOpenRate: 93.6, //时间开动率
funOpenRate: 95.8, //性能开动率
successRate: 97.5, //合格品率
oeeRate: 87.43, //OEE
},
actual: {
//实际值
timeOpenRate: 100.0,
funOpenRate: 0.0,
successRate: 0.0,
oeeRate: 0.0,
},
last: {
//同期
timeOpenRate: 0.0,
funOpenRate: 0.0,
successRate: 0.0,
oeeRate: 0.0,
},
};

const list = Object.keys(obj.normal).reduce((pre, next) => {
const now = {
type: next,
};
Object.keys(obj).map((item) => {
now[item] = obj[item][next];
});
pre.push(now);
return pre;
}, []);
console.log(`r`, list);

//方法二
Object.keys(obj.normal).map((e) => ({
type: e,
...Object.fromEntries(
Object.keys(obj).map((key) => {
return [key, obj[key][e]];
})
),
}));

// [
// {
// type: 'timeOpenRate',
// actual:'', //actual.timeOpenRate的值
// normal:'',//normal.timeOpenRate的值
// last:'',//last.timeOpenRate的值
// },
// {
// type: 'funOpenRate',
// actual:'',//actual.funOpenRate的值
// normal:'',//normal.funOpenRate的值
// last:'',//last.funOpenRate的值
// },
// {
// type: 'successRate',
// actual:'',
// normal:'',
// last:'',
// },
// {
// type: 'oeeRate',
// actual:'',
// normal:'',
// last:'',
// },
// ]

多数组对象转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// dimensions: ['shiftDate', 'A', 'B', 'C', 'D'],

// [
// {
// shiftDate: '20211123',
// B:''oeeRate, //item.oeeRate的值
// D:''oeeRate,//item.oeeRate的值
// },
// {
// shiftDate: '20211112',
// A:''oeeRate, //item.oeeRate的值
// B:''oeeRate,//item.oeeRate的值
// },
// ]

let arr = [
[
{
timeOpenRate: 100.0,
teamGroup: "B",
funOpenRate: 4738500.0,
successRate: 0.0,
shiftDate: "20211123",
oeeRate: 0.0,
},
{
timeOpenRate: 96.67,
teamGroup: "D",
funOpenRate: 6700200.0,
successRate: 0.0,
shiftDate: "20211123",
oeeRate: 0.0,
},
],
[
{
timeOpenRate: 100.0,
teamGroup: "A",
funOpenRate: 170908400.0,
successRate: 0.0,
shiftDate: "20211112",
oeeRate: 0.0,
},
{
timeOpenRate: 100.0,
teamGroup: "B",
funOpenRate: 181821900.0,
successRate: 0.0,
shiftDate: "20211112",
oeeRate: 0.0,
},
],
];
arr.map((item) => {
const obj = {};
item.map((i) => {
obj.shiftDate = i.shiftDate;
obj[i.teamGroup] = i.oeeRate;
});
return obj;
});

对象映射 mapping

1
2
3
4
5
6
7
8
9
10
11
//订单状态颜色
handlerStatus(status) {
const mapping = {
10: "info",
20: "warning",
30: "error",
40: "success",
50: "primary",
};
return mapping[status];
},

同名属性赋值

1
2
3
4
// 遍历child(未赋值)中的属性,将parent中的同名属性赋值给child
Object.keys(this.child).map((key) => {
this.child[key] = this.parent[key];
});

同名属性赋值(浅拷贝)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const {
actualCustomerCode,
actualCustomerName,
demandId,
demandMonth,
machineCode,
productParentCode,
productParentName,
saleNetType,
saleNetworkCode,
sellerCode,
} = form;
this.ssdhOrderDemand = Object.assign(
{},
{
actualCustomerCode,
actualCustomerName,
demandId,
demandMonth,
machineCode,
productParentCode,
productParentName,
saleNetType,
saleNetworkCode,
sellerCode,
}
);

数组对象中按顺序插入另一个数组的子项

1
2
3
4
5
6
7
8
9
10
let list = [
{ a: 1, b: 2 },
{ a: 3, b: 4 },
{ a: 5, b: 6 },
];

let subList = [{ c: 11 }, { c: 22 }, { c: 33 }];
let arr = list.map((item, index) => Object.assign({}, item, subList[index]));

console.log(arr);

对象转数组

1
2
3
4
5
let obj = { a: 1, b: 2 };
let arr = [{ a: 1 }, { b: 2 }];
Object.keys(obj).map((i) => ({ [i]: obj[i] }));

Object.entries(obj).map(([k, v]) => ({ [k]: v }));

||运算符的顺序

1
2
3
4
5
6
let a = "";
let b = "";
let c = "cc";
a = b || c ? 123 : 321;

console.log(a); //123

上面示例的顺序是先判断 b 或 c 是否存在,再进行三元运算

1
2
3
4
let a = "";
let b = "bb";
let c = "cc";
console.log(a == b || c); //cc

最后判断不是a是否等于 b 或 c,而是 a 是否等于 b,c 是否存在.
正常应该是两边都判断是否相等

1
console.log(a == b || a == c);

return

只有一层 if 时,可以使用return中断.
多层 if 时,建议设置变量,例如flag

1
if (flag) return;

filter

1
2
3
4
5
6
7
//filter =>map,push
let arr = [];
let item = "A";
// this.category.map(i => {
// item.includes(i.key) ? arr.push(i) : "";
// });
arr = this.category.filter((i) => item.includes(i.key));

toFixed

oFixed()方法可把 Number 四舍五入为指定小数位数的数字.

reduce

接收 4 个参数,acc(累加器),cur(当前值),idx(当前索引),src(源数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
//计算数组中每个元素出现的次数
var names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];

var countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 如果code相同,就给name字符串加1做出区分.(比如,南风仓库1)
let data = [
{
class: "a",
code: "H1",
name: "东仓库",
},
{
class: "b",
code: "H2",
name: "南仓库",
},
{
class: "c",
code: "H2",
name: "南仓库",
},
{
class: "d",
code: "H3",
name: "西仓库",
},
];

const r = data.reduce(
(prev, next) => {
const length = prev.filter((item) => item.code === next.code).length || "";
prev.push({
...next,
name: `${next.name}${length}`,
});
return prev;
},
[data[0]]
);

console.log(r);
1
2
3
4
5
6
7
8
//数组去重
let myArray = ["a", "b", "a", "b", "c", "e"];
let ordArray = myArray.reduce((acc, cur) => {
if (acc.indexOf(cur) === -1) {
acc.push(cur);
}
return acc;
}, []);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let list = [
{
arr: [1, 2, 3],
},
{
arr: [1, 2, 3, 4, 5],
},
{
arr: [1, 2],
},
];

//如何取出最长的一个数组出来

list.reduce((res, { arr }) => (res.length > arr.length ? res : arr), []);

fill 数据填充

后端只返回空数组或者短于要求的数组,其他填充为 0,或者固定值.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let list = [
{
arr: [1, 2, 3],
},
{
arr: [1, 2, 3, 4, 5],
},
{
arr: [1, 2],
},
];
let arr = [...list, ...[...Array(12 - list.length)].fill(0)].fill(
{ value: 0 },
list.length,
12
);

判断空对象

1
2
3
4
5
6
7
function isEmpty(value) {
return (
value === null ||
value === undefined ||
(typeof value === "object" && Object.keys(value).length === 0)
);
}

修改数组对象

1
2
3
4
const { hyBlock, cpBlock, txBlock } = data.data
this.list = hyBlock.map(item =>({label: item.labelTitle, value: item.labelId}))
//同名可以使用解构
this.list = hyBlock.map({labelTitle, labelId}) =>({labelTitle, labelId}))

文章摘要截取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//解析字符串
htmlSlice(content){
if(content){
let re1 = new RegExp("<.+?>","g");//匹配html标签的正则表达式,"g"是搜索匹配多个符合的内容
let re2 = new RegExp("&.+?;","g");//匹配html标签的正则表达式,"g"是搜索匹配多个符合的内容
let msg1 = content.replace(re1,'');//执行替换成空字符
let msg = msg1.replace(re2,'"');//执行替换成空字符

if(msg.length > 100){
msg = msg.substr(0,100)
}
console.log(msg.length,"msg");
return msg
}
}

//css限定行数
.content {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
}

表单重置

1
2
3
4
5
6
7
8
9
10
11
resetForm(opt) {
Object.keys(opt).map((item) => {
if (opt[item] instanceof Array) {
opt[item] = []
} else if (opt[item] instanceof Object) {
opt[item] = {}
} else {
opt[item] = ''
}
})
},

使用 picker 组件自制时间区间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//view
<picker mode="date" :value="defaultTime" :end="startDate" fields="day" @change="getData('start',$event)">
<view class="line-box1 u-margin-right-10">{{ "起始日期" }}</view>
</picker>
<picker mode="date" :end="endDate" fields="day" @change="getData('end',$event)">
<view class="line-box1 u-margin-right-10">{{ "截止日期" }}</view>
</picker>
//script
data() {
const timeD = this.$u.timeFormat(
new Date().getTime() - 7 * 24 * 3600 * 1000 //,默认7天范围
);
},
computed: {
startDate() {
//要return的日期比endDate数值小或===
return this.endDate;
},
endDate() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
return `${year}-${month}-${day}`;
},
},

格式化字符串时间

1
2
3
4
//将'20211102'格式化为'2021-11-02'
formDateStr(str){
return str.slice(0,4)+'-'+str.slice(4,6)+'-'+str.slice(6)
},

仅修改对象数组里某个值

1
2
3
4
5
6
7
8
9
const list = [
{ name: "aaa", age: 10 },
{ name: "bbb", age: 11 },
{ name: "ccc", age: 12 },
];
const newList = list.map((item) => ({
...item,
age: item.age + 1,
}));

判断类型的方法 toString()

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
Object.prototype.toString.call(""); // [object String]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call(new Error()); // [object Error]
Object.prototype.toString.call(document); // [object HTMLDocument]
Object.prototype.toString.call(window); //[object global] window 是全局对象 global 的引用

使用函数封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export function filterClassName(names) {
const type = Object.prototype.toString.call(names).slice(8, -1).toLowerCase();
switch (type) {
case "array":
return names.length ? names.join(" ") : "";
case "object":
const keys = Object.keys(names);
let newClass = "";
return keys.length
? keys.forEach((key) => (newClass += names[key] + " "))
: "";
case "string":
return names;
case "number":
return names.toString();
default:
return "";
}
}

Json 转 tree

一维数组转树形结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const list = [
{
name: "Tom",
age: "25",
team: "A",
item: "SSR",
itemNum: "300",
},
{
name: "Tom",
age: "25",
team: "A",
item: "SSk",
itemNum: "500",
},
{
name: "Jim",
age: "22",
team: "B",
item: "KKR",
itemNum: "300",
},
{
name: "Jim",
age: "22",
team: "B",
item: "KKS",
itemNum: "500",
},
];
const finList = [
{
name: "Tom",
age: "25",
team: "A",
itemGroup: [
{
item: "SSR",
itemNum: "300",
},
{
item: "SSk",
itemNum: "500",
},
],
},
{
name: "Jim",
age: "22",
team: "B",
itemGroup: [
{
item: "KKR",
itemNum: "300",
},
{
item: "KKS",
itemNum: "500",
},
],
},
];

function convert(list) {
let arr = [];
list.forEach((i, index) => {
let { name, age, team, item, itemNum } = i;
if (!arr[name]) {
arr[name] = {
name,
age,
team,
teamGroup: [],
};
}
arr[name].teamGroup.push({
item,
itemNum,
});
});
return Object.values(arr);
}
let aaa = convert(list);
console.log(aaa);

不同 id 的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let flatArr = [
{ id: 1, title: "解忧杂货铺1", parent_id: 0 },
{ id: 2, title: "解忧杂货铺2", parent_id: 0 },
{ id: 3, title: "解忧杂货铺2-1", parent_id: 2 },
{ id: 4, title: "解忧杂货铺3-1", parent_id: 3 },
{ id: 5, title: "解忧杂货铺4-1", parent_id: 4 },
{ id: 6, title: "解忧杂货铺2-2", parent_id: 2 },
];
function convert(list) {
const res = [];
const map = list.reduce((res, v) => ((res[v.id] = v), res), {});
for (const item of list) {
if (item.parent_id === 0) {
res.push(item);
continue;
}
if (item.parent_id in map) {
const parent = map[item.parent_id];
parent.children = parent.children || [];
parent.children.push(item);
}
}
return res;
}
let returnTree = convert(flatArr);
console.log(returnTree);