https://oss-images-1310293673.cos.ap-chongqing.myqcloud.com/static/2022/12/2022-12-09/WechatIMG146.png
|

TypeScript 使用技巧(一)

1. 枚举类型 1.1 获取枚举(enum)的键(key) enum MyEnum { Key1 = 'Value1', Key2 = 'Value2', Key3 = 'Value3', } type MyEnumKeys = keyof typeof MyEnum; // MyEnumKeys 的类型为 "Key1" | "Key2" | "Key3" 1.2 获取枚举(enum)的值(value) enum MyEnum { Key1 = 'Value1', Key2 = 'Value2', Key3 = 'Value3', } type MyEnumValues = MyEnum[keyof typeof MyEnum]; // MyEnumValues 的类型为 "Value1" | "Value2" | "Value3" 2.新特性 satisfies satisfies 运算符提供了一种为值添加类型注解而不丢失值推理的方法。 2.1 使用satisfies的强类型 URLSearchParams satisfies非常适合强类型化函数,这些函数通常使用更宽松的类型。 在使用 URLSearchParams 时,它的参数通常是 Record<string, string | string[]> 。这是一种非常松散的类型,并不强制执行任何特性的键。通常情况下,你需要创建一些搜索参数并将它们传递给 URL。因此,这种松散的类型最终会变得相当危险。

Typescript奇怪的符号

1. ! 非空断言操作符 概念:在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 !可以用于断言操作对象是非 null 和非 undefined 类型。具体而言,x! 将从 x 值域中排除 null 和 undefined。 使用场景: 1.1 忽略 undefined 和 null 类型 function myFunc(maybeString: string | undefined | null) { // Type 'string | null | undefined' is not assignable to type 'string'. // Type 'undefined' is not assignable to type 'string'. const onlyString: string = maybeString; // Error const ignoreUndefinedAndNull: string = maybeString!; // Ok } 1.2 调用函数时忽略 undefined 类型

一次性整明白的 React Hook

useState useState 可以说是我们日常最常用的 hooks 之一了,在实际使用过程中有一些简单的小技巧能帮助你提升性能 & 减少出 bug 的概率。 使用惰性初始值官方文档 通常我们会使用以下的方式初始化 state const [count, setCount] = useState(0); 对于简单的初始值,这样做完全没有任何性能问题,但如果初始值是根据复杂计算得出来的,我们这样写就会产生性能问题。 const initialState = heavyCompute(() => { /* do some heavy compute here*/ }); const [state, useState] = useState(initialState); 相信你已经发现这里的问题了对于 useState 的初始值,我们只需要计算一次,但是根据 React Function Component 的渲染逻辑,在每一次 render 的时候,都会重新调用该函数,因此 initialState 在每次 render 时都会被重新计算,哪怕它只在第一次渲染的时候被用到,这无疑会造成严重的性能问题,我们可以通过 useState 的惰性初始值来解决这个问题。 // 这样初始值就只会被计算一次 const [state, setState] = useState(() => heavyCompute(() => { /* do some heavy compute here*/ }) ); 不需要把只需要计算一次的东西直接放在函数组件内部顶层的 block 中

package.json 与 package-lock.json 的关系

1. Package.json Package.json 用来描述项目及项目所依赖的模块信息。 通过 npm 管理,使用npm init -y就可以自动生成 package.json,安装包依赖关系都由 package.json 来管理。 语义版本控制 版本号由三部分组成: major.minor.patch,对应的就是 主版本.次版本号.修补版本号。 例如: 1.2.3,主要版本 1,次要版本 2,补丁 3。 补丁中的更改表示不会破坏任何内容的错误修复 次要版本的更改表示不会破坏任何内容的新功能 主要版本的更改表示了一个破坏兼容性的大变化。如果用户不适应主要版本,则内容将无法正常工作。 安装依赖包的版本如何指定 相信大家都会经历过,我们安装一些依赖包的时候,版本号前面都会带^ 或者 ~ 的符号,那么大家有思考过这两个符号代表的是什么吗? ^ 会匹配最新的大版本依赖包,比如^1.2.3 会匹配所有 1.x.x 的包,包括 1.3.0,但是不包括 2.0.0 ~ 会匹配最近的小版本依赖包,比如~1.2.3 会匹配所有 1.2.x 的版本,但是不包括 1.3.0 * 安装最新版本的依赖包,比如*1.2.3 会匹配 x.x.x 那么该如何选择呢?当然你可以指定特定的版本号,直接写 1.2.3,前面什么前缀都没有,这样固然没问题,但是如果依赖包发布新版本修复了一些小 bug,那么需要手动修改 package.json 文件;^和~ 则可以解决这个问题。 但是需要注意^版本更新可能比较大,会造成项目代码错误 ❌,所以建议使用~ 来标记版本号,这样可以保证项目不会出现大的问题,也能保证包中的小 bug 可以得到修复。 版本号写*,这意味着安装最新版本的依赖包,但缺点同上,可能会造成版本不兼容,慎用 ⚠️。 多人开发时依赖包安装的问题 看了上面版本号的指定后,我们可以知道,当我们使用了^和~来控制依赖包版本的时候,多人开发,就有可能存在大家安装的依赖包版本不一样的情况,就会存在项目运行的结果不一样。 举个例子: 假设我们在项目中安装了 vue,当我们运行npm install vue -save 的时候,在项目中的 package.json 的 vue 版本是 vue: ^3.

前端下载图片或者文件的方式

前端下载资源的方式 目前前端直接下载 web 服务器或者 CDN 静态资源的方式有两种,一个是利用 <a>标签,另一个通过 window.open() 函数。今天重点讲一下 <a> 标签。 <a>标签 标签就是 html 中的超链接标签,但是用过这个标签的同学应该都有这种印象,当超链接链接的内容是图片、视频或者 pdf 时,点击超链接往往会在浏览器的新标签页中打开对应的资源,而不是开始下载。但是其他像压缩包这样的资源,也就是浏览器没办法直接打开的资源则会直接开始下载。问题来了,怎么样让所有的文件都 默认下载而不是打开呢? HTML5 给 <a> 标签增加了一个 download 属性,当 <a> 标签戴上了 download 属性时,点击超链接则会被浏览器解析为下载而不是打开。 下面我们实际操作一下 一个不带 download 属性的 <a> 标签案例: 浏览器打开之后,点击下载图片查看效果。 随后浏览器打开了图片,但是并没有下载。 <a>标签添加 download 属性后,在试一次 添加 download 属性后,再次点击 可以看到我们的图片已经下载,达到了我们想要的效果。 我们把 <img> 和 <a> 标签的路径换成一张网络图片,而非本地的图片。 点击下载图片,会发现并没有下载,而是在浏览器中打开了图片。 注意: 如果你的图片渲染不出来,请在标签内加入 <meta name="referrer" content="no-referrer"> 我们开始分析没有下载的原因 很可能是浏览器的 同源策略 导致 download 属性失效造成的。同源策略是浏览器的一种安全策略,所谓的同源指的是 URL 地址里面的协议、域名和端口号均相同,如果一个站点开启了同源策略,也称为禁止跨域访问;这时,这个站点的资源自允许在该站点内部跳转和访问,不允许被第三方站点访问和跳转。我们这个案例中由于源 cnblogs 的服务器设置了禁止跨域,在我们这个场景下的表现就是不能在非 cnblogs 站点下直接下载 cnblogs 文件,所以这里 download 属性会失效,而失效之后做的仅仅是跳转功能。

总结 ES2015 的所有新特性

总结 ES2015 的所有新特性 💥 ES2015(ES6)是改动最大的一个版本,大体如下: 🍏 let、const关键字和块级作用域 在ES6来临之前,我们习惯于var 关键字声明变量,var声明的变量是属于全局变量,最终会挂载到window对象,这一操作可能会引起一些意外的错误。所以在ES6中加入了const和let 关键字来声明变量。 let v = 100 v = 200 const a = 1 a = 2; // Uncaught TypeError: Assignment to constant variable. // 报错,const关键字声明的是一个常量,是不可以改变的(针对于基本数据类型) { var a = 100 } { let b = 100 } console.log(a) // output: 100 console.log(b) // 报错,b is not defined. // let声明的变量只能在当前的`块级作用域({} 之间的区域)`中使用 ⚠️ let、const声明的变量存在一个暂时性死区的问题 a = 1; let a = 0;// Uncaught ReferenceError: Cannot access 'a' before initialization // 暂时性死区是指使用let、const关键字声明的变量在定义之前是不可以使用的,声明之后才可以使用。 🍐 函数的扩展(函数形参的默认值、箭头函数) 函数默认值