ES6
1. 解构与改名
2. 数组去重
1
| const c = [...new Set([...a, ...b])];
|
3. 数组扁平化
4. ?? or ||
??
仅在左侧为 null
, undefined
时跳到右侧
||
为 0
, ''
, NaN
, null
, undefined
(这五个称为假值)
* []
{}
的值为 true
* ??
推荐和 ?.
共用
typescript
一、操作符
1. void
作为函数返回值类型,表示不关注返回值类型,可以是任意值
2. 非空断言 !
使用场景:ref
3. 键值获取 keyof
1 2 3 4 5
| type Person = { name: string; age: number; } type PersonKey = keyof Person;
|
使用场景:遍历一个对象的所有 key 时(拿不到类型时可以用 keyof typeof)
1 2 3
| (Object.keys(params) as (keyof feedbackParams)[]).forEach((key) => { formData.append(key, params[key]); });
|
4. 联合类型 | 交叉类型 &
不是数学上的交集并集!
& 交叉类型:产生的新集合包含原各集合的所有属性(语义上的“且”)
| 联合类型:产生的新集合是一个 select
,可以是 A,也可以是 B,但不能同时拥有 A 和 B (语义上的“或”)
使用场景:继承
二、泛型工具
Partial
将泛型中全部属性变为可选的。
Required
将泛型中全部属性变为必选的。
Record<K, T>
常用于定义对象。 Record<string, unknown>
Pick<T, K>
取键值对。
Pick<Animal, "name" | "age">
Omit<T, K>
去键值对。
Omit<Animal, 'name'|'age'>
三、Work with React
1. 声明函数式组件
这种方式会在 props 里显式声明 children
1 2 3 4 5 6
| const App: React.FC<AppProps> = ({ message, children }) => ( <div> {message} {children} </div> )
|
2. 使用 typeof 减少冗余的 props 类型导出
1 2
| import { Recent } from '@mercury/component' type RecentProps = React.ComponentProps<typeof Recent>
|
3. React 事件类型定义
1 2 3 4 5 6 7 8 9
| type Props = { onClick: (event: React.MouseEvent<HTMLInputElement>) => void onChange: (event: React.ChangeEvent<HTMLInputElement>) => void onkeypress: (event: React.KeyboardEvent<HTMLInputElement>) => void onBlur: (event: React.FocusEvent<HTMLInputElement>) => void onFocus: (event: React.FocusEvent<HTMLInputElement>) => void onSubmit: (event: React.FormEvent<HTMLFormElement>) => void onClickDiv: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void }
|
对应的 handler 类型
1 2 3
| type ChangeEventHandler<T = Element> = EventHandler<React.ChangeEvent<T>> type KeyboardEventHandler<T = Element> = EventHandler<React.KeyboardEvent<T>> type MouseEventHandler<T = Element> = EventHandler<React.MouseEvent<T>>
|
4. 类型断言/类型守卫
- 类型断言
- 类型守卫:通过 if 自动推断类型。
- 类型判断:
typeof 基本类型
- 实例判断:
instanceof 类(非接口)
- 属性判断:
字段 in 接口(所实现的实例)
in
其实是 js 自带语法,应用在实例上
- 字面量相等判断:
==
, ===
, !=
, !==
,适用于枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const input1: string | number; if (typeof input1 == 'string') { }
class A {}; class B {}; const input2: A | B; if (input2 instanceof A) { }
interface Foo { foo: string; } interface Bar { bar: string; } const input3: Foo | Bar; if ('foo' in input3) { }
|
自定义类型守卫函数:代码随便写,返回值保证是参数 is 类型
1 2 3 4
| function isBatman (man: any): man is Batman { return man && man.helmet && man.cloak; }
|
5. useEffect的時機
每次组件渲染后都执行:
只会在组件首次渲染后执行一次:
1
| useEffect(() => {}, []);
|
6. 我就是不想單獨聲明類型!
看例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| type BasicInfo = { accountMembers: Array<{ micComId: string; companyNameCn: string; establishYears: string; capitalAmount: string; mainCategory: string; mainCategoryYearAvgInvest: string; portraitUrl: string; smtCaseUrl: string; advancedMember: boolean; }>; };
type accountMembers = BasicInfo["accountMembers"];
type accountMember = BasicInfo["accountMembers"][number];
type UpdateArchiveDataType = Parameters<typeof updateArchive>[0];
|
Trick
if 条件太长时
1 2 3 4 5 6 7 8
| if( type == 1 || type == 2 || type == 3 || type == 4 || ){ }
|
↓
1 2 3 4
| const condition = [1, 2, 3, 4]; if (condition.includes(type)) { }
|
升降 CSS 优先级
内联 > ID > 类/伪类/属性 > 元素/伪元素
- (升优先级)自我重复,提高选择器的优先级:
.{className}.{className}
- (降优先级)属性选择器
[id='{targetId}']
替代 #{targetId}
以获得与 .{className}
相同的优先级
- 优先级是权重相加制,更具体的选择器拥有更高的优先级
import type がウザい!
1
| import { type RecentProps } from '@mercury/component'
|
表單提交數組/對象數組
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 params = { clusterId: currentCluster.clusterId, instanceIdList: [currentInstance.instanceId], mavenInfoList: [currentPlugin], }; const urlSearchParams = new URLSearchParams(); Object.keys(params).forEach((key) => { if (key === "mavenInfoList") { params[key].forEach((item, index) => { Object.keys(item).forEach((itemKey) => { if (item[itemKey] === null) { item[itemKey] = ""; } urlSearchParams.append(`${key}[${index}].${itemKey}`, item[itemKey]); }); }); } else if (key === "instanceIdList") { params[key].forEach((item, index) => { urlSearchParams.append(`${key}[${index}]`, item); }); } else { urlSearchParams.append(key, params[key]); } });
|
巧用對象來去重
- 對象數組,根據某字段來去重
1 2 3 4 5 6 7 8 9 10 11
| const newNodes = [];
const obj = {}; newNodes.forEach((item) => { obj[item.customId] = item; }); const newNodes2 = []; Object.keys(obj).forEach((key) => { newNodes2.push(obj[key]); });
|
- 對象數組,獲取某字段的枚舉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const clusterTypeEnum = {}; const allCluster = []; allCluster.forEach((item) => { clusterTypeEnum[item.parKey] = { text: item.parKey }; });
{ "user-service": { "text": "user-service" }, "api-service": { "text": "api-service" }, "route": { "text": "route" } }
|
复制到剪贴板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export const copyToClipboard = async (text) => { try { if (navigator.clipboard && window.isSecureContext) { await navigator.clipboard.writeText(text); message.success("复制成功"); } else { const textarea = document.createElement("textarea"); textarea.value = text; document.body.appendChild(textarea); textarea.select(); document.execCommand("copy"); message.success("复制成功"); document.body.removeChild(textarea); } } catch (err) { message.error("复制失败", err); } };
|
下载
使用axios
1 2 3 4 5 6 7 8 9
| axios.get("XXX", { responseType: "blob" }).then((res) => { const blob = new Blob([res.data]); const downloadADom = document.createElement("a"); downloadADom.href = URL.createObjectURL(blob); downloadADom.download = fileName; downloadADom.target = "_blank"; downloadADom.click(); URL.revokeObjectURL(downloadADom.href); });
|
上傳
URL操作
1 2 3 4 5 6 7 8 9 10
| function addParamToUrl(url, paramName, paramValue) { let myUrl = new URL(url); myUrl.searchParams.set(paramName, paramValue); return myUrl.href; }
const productUrl = "http://example.com/product"; const newUrl = addParamToUrl(productUrl, "tradeFrom", "3_1");
console.log(newUrl);
|
git
慎用 –hard!
回溯到某次提交
撤回上一次提交
已经提交到远程了:
还没提交到远程,只是本地暂存了:
1
| git reset XXX # XXX 为最近一次提交,不要用 --hard
|