最近写业务也有一段时间了,感觉做业务和平时自己写项目差距颇大,接受这些需要时间和练习,不过收获还是挺多的,不管是React的使用,还是antd的api熟悉程度。时间跨度有点长(小一个月),有些东西记不清楚了,就先分享记得深的吧。
js
||
与 ??
的区别
这两个运算符,大家可能 ||
用的比较多一些,一般用来赋默认值,例如
也即如果 ||
左边在JavaScript可以转化为 Truthy(真值) - 术语表 | MDN ,就取左边的值,否则就取右边的值。
而 ??
其实我也是近一个月才知道的,只有运算符左侧的值为 null
或 undefined
时,才会返回右侧的值。
export 和 import 的 使用技巧
试想一下,现在有这样一个场景,你封装了一个组件,写 typescript 的时候想要导出一个 interface,例如
import * as React from "react";
export interface IProps {name: string;
}
export interface IUser {age: number;
}
const CustomTableFilter: React.FC<IProps> = (props: IProps) => {const { name } = props;return <div>{name}</div>;
};
export default CustomTableFilter;
然后在其他地方想引入这个组件,就可以这样写
import CustomTableFilter, { IProps, IUser } from "./components/CustomTableFilter";
如果我们把 默认导出的 CustomTableFilter
和 { IProps, IUser }
调整一下位置,就会报错
有关更多 import 的用法可以参考 import - JavaScript | MDN (mozilla.org)
ts
is
is
属于typescript里面的一个类型保护机制,类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型。
例如:
function isString(value: unknown): value is string {return typeof value === 'string'
}
你可能会好奇,这和下面的代码有什么区别
function isString(value: unknown): boolean {return typeof value === 'string'
}
下面我们进行测试
如果是使用is做类型保护,在编译时期,我们便能发现一些问题,而如果我们调整为下面这样,test传入的参数为any类型的话,编译时期是发现不了问题的,运行时期可以发现错误
这里放一些 ahooks 判断类型的方法
export const isObject = (value: unknown): value is Record<any, any> =>value !== null && typeof value === 'object';
export const isFunction = (value: unknown): value is Function => typeof value === 'function';
export const isString = (value: unknown): value is string => typeof value === 'string';
export const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
export const isNumber = (value: unknown): value is number => typeof value === 'number';
export const isUndefined = (value: unknown): value is undefined => typeof value === 'undefined';
组件封装
slider 和 inputNumber 联动组件
在线链接 CodeSandbox
这个是我最近要做的需求 – 选择带宽 ,如下图所示,简单一点理解就是 Slider - Ant Design 、InputNumber - Ant Design 和 select 之间的 联动,可是当我 上手开始实现组件的时候,人都懵了,列一下我当时遇到的问题。
- slider的 4 个刻度均分整个滑动条
- 输入框 的值 和 tooltip 对应
- 输入框 点击 加或者减 的时候 和 tooltip 对应
- 单位 和 slider 之间的 联动
我们首先看看第一个问题,1G = 1000M
意味着 滑动条不是均分的,而slider 的 marks 属性 用来标记刻度,值为number,如果我想均分,就意味着 刻度 和 slider 的 value 不对应,所以 应该建立一种转化关系,将 slider 的 value 转化为 tooltip 。于是,根据 mark 和 转化关系 ,我写了一个 formatter 函数
const marks: SliderMarks = {0: "1M",33: "1G",66: "10G",100: "100G",
};
const formatter = (value: number) => {// 将真实值转化为显示值// return inputRawif (value < 33) {// 1M~1Greturn value === 0 ? "1" : `${value * 30}`;}if (value >= 33 && value < 66) {return value === 33 ? "1" : `${(((value - 33) / 33) * 9 + 1).toFixed(1)}`;}if (value >= 66 && value < 99) {return value === 66? "10": `${(((value - 66) / 33) * 90 + 10).toFixed(1)}`;}return "100";
};
第二个和第三个问题,正是我昨天晚上很头疼却不能解决的,我的想法是inputNumber 组件的 value 要想和 slider的 tooltip 保持一致 ,就必须经过 formatter 函数处理,可是 事实却告诉我想法错误,如果这样设置 会改变 onChange 监听函数的 传参,本来传递的 是 inputValue , 组件行为正常,就是显示不正确,而现在修改为 formatter 之后的值,需要进行 还原 为inputValue ,可是此行为会导致一些其他问题,比如点击 加和减 会出现 值 跳跃,并且不会与 toottip 同步。当时陷入了牛角尖,后来问了一个学长,共同商量了一会后,学长说可以把 显示的 tooltip 的值单独拿出来 作为一个变量,这样就不用担心值同步的问题了(inputValue来控制slider的进度,inputRaw来控制输入框和tooltip的显示)。新思路很快解决之前的困局,加上我今天早上的调试和修改,也解决了 单位 和 slider 之间的联动问题。
不过还是要说一下,和单位联动其实有挺多坑的,比如 当前是Mbps,你修改了 inputNumber的值,同时slider 的 滑动条应该也改变,这里需要分情况讨论,1M,1000M,10000M等等,需要根据不同的区间来匹配值。还有 select 切换单位时触发的改变 和 改变 inputNumber 时的 单位是不一样的,落后一个状态, 原因在于 setState 的异步更新。
Vscode 快捷键
功能 | 按键 |
ctrl + D | 将选择添加到下一个查找匹配 |
alt + 单击 | 插入光标 |
ctrl + alt + ↑/↓ | 在上/下插入光标 |
ctrl + U | 撤消上一个光标操作 |
这里做一下演示
最后