1. 現在のフロントエンド ショーの書き込み操作の一部
最初に私が見た書き方のいくつかをリストしてみましょう:)
1. シャトルをインターフェイス (または入力)
ナゲッツに関する記事がたくさんありますが、 というときはデータ構造を宣言するのにや をTypeScript
使うべきではないでしょうか?このような:interface
type
type User = {
nickname: string
avatar?: string
age: number
}
interface User {
nickname: string
avatar?: string
age: number
}
では、他の方法では入力の種類が制限され、これで完了、マスターしましたTypeScript
、そして給与は 3000 増加できないでしょうか? ? ?
ここで当社がデコレータ以外のパラメータや設定パラメータを定義するために
不允许
直接使用していることを説明します。interface
type
任何数据类型
2. 体操の種類
属性が読み取り専用になっているか、豚と犬のタイプが結合されているか、豚の尻尾が失われているか、牛が本当に自慢しているかのいずれかです。
タイプ体操はたくさんのトリックを行いました。昨日こう言いました。TypeScript最好玩的就是类型体操, 也恰好是最不应该出现的东西
3.hook
無限の神話
いつから始まったのかは分かりませんが、hook
だんだんと人気が高まってきています。書けないフロントエンドプログラマはhook
もはや上級プログラマではなく、use
何もせずにその凄さを発揮できないと聞きました。
4.axios
インターセプトが上手い
axios
の記事を検索してください。拦截器
このキーワードのない記事は、axios
のハイエンドの使用法とは見なされません。
2. さまざまなフロントエンド操作の一部
装饰器
昨日の記事では、構成ベースの要件を達成するためにフロントエンドで使用することについて触れましたが、今日は実際に、フロントエンドでエレガントにオブジェクト指向を実現する方法に焦点を当てたいと思います。
、 、Java
およびその他のコードを作成したバックエンド プログラマがよく知っておくべきいくつかの概念は次のとおりです。SpringBoot
JPA
- 抽象化: すべてを関連するクラスとオブジェクトに抽象化できます。
- オブジェクト指向: 継承、カプセル化、ポリモーフィズムなどの機能を備えたオブジェクト指向の設計思考
- 切面: 没有什么是切一刀解决不了的,如果一刀不行, 那就多来几刀。
- 注解: 没有什么常量是不能使用注解来配置的, 也没有什么注解是切面想切还能躲得掉的
- 反射: 没有什么是暴力拿取会失败的, 即使失败也没有异常是丢不出来的
- 实体: 没有什么是不能抽象到实体上的, 万物皆唯一。
- 很多: 还有很多,以上描述比较主观和随意。
于是我们开始把后端思维往前端来一个个的转移:)
1. 抽象和面向对象
与后端的交互数据对象、 请求的API接口都给抽象到具体的类上去,于是有了:
Service
API请求类
abstract class AbstractService{
// 实现一个抽象属性 让子类们实现
abstract baseUrl!: string
// 再实现一些通用的 如增删改查之类的网络请求
// save()
// getDetail()
// deleteById()
// select()
// page()
// disabled()
// ......
}
Entity
数据实体基类
abstract class AbstractBaseEntity<S extends AbstractService> {
abstract service!: AbstractService
// 任何数据都是唯一的 ID
id!: number
// 再来实现一些数据实体的更新和删除方法
save(){
await service.save(this.toJson())
Notify.success("新增成功")
}
delete(){
service.deleteById(this.id)
Notify.success("删除成功")
}
async validate(scene: EntityScene):Promise<void>{
return new Promise((resolve,reject)=>{
// 多场景的话 可以Switch
if(...){
Notify.error("XXX校验失败")
reject();
}
resove();
})
}
// ......
}
- 子类的实现:)
class UserEntity extends AbstractUserEntity<UserService>{
service = new UserService()
nickname!: string
age!: number
avatar?: string
// 用户是否成年人
isAdult(): boolean{
return this.age >= 18
}
async validate(scene: EntityScene): Promise<void> {
return new Promise((resove,reject)=>{
if(!this.isAdult()){
Notify.error("用户未成年, 请确认年龄")
reject();
}
await super.validate(scene)
})
}
}
View
视图调用
<template>
<el-input v-model="user.nickname"/>
<el-button @click="onUserSave()">创建用户</el-button>
</template>
<script setup lang="ts">
const user = ref(new UserEntity())
async function onUserSave(){
await user.validate(EntityScene.SAVE);
await user.save()
}
</script>
2. 装饰器/切面/反射
装饰器部分的话,昨天的文章有提到一些了,今天主要所说反射和切面部分。
在 TypeScript
中, 其实装饰器本身就可以理解为一个切面了, 这里与 Java
中还是有很多不同的, 但概念和思维上是基本一致的。
反射 Reflect
是 TypeScript
中比较坑的一个存在, 目前主要是依赖 reflect-metadata
这个第三方库来实现, 将一些元数据存储到 metadata
中, 在需要使用的时候通过反射的方式来获取。 可以参考这篇文章:TypeScript 中的元数据以及 reflect-metadata 实现原理分析
在实际使用中, 我们早前用的是 class-transformer
这个库, 之前我对这个库的评价应该是非常高的: “如果没有 class-transformer 这个库, TypeScript 狗都不写。”
确实很棒的一个库,但是在后来,我们写了个通用的内部框架, 为了适配 微信小程序端
以及 uniapp
端, 再加上有一些特殊的业务功能以及 class-transfromer 的写法和命名方式我个人不太喜欢的种种原因, 我们放弃了这个库, 但我们仿照了它的思想重新实现了一个内部使用的库,做了一些功能的阉割和新特性的添加。
核心功能的一些说明
-
通过反射进行数据转换
如将后端API返回的数据按照前端的数据结构强制进行转换, 当后端数据返回乱七八糟的时候,保证前端数据在使用中不会出现任何问题, 如下 demo
class UserEntity { @Type(String) phone!: string; @Type(RoleEntity) roleInfo!: RoleEntity: @Type(DeptEntity) @List @Default([]) deptInfoList!: DeptEntity[] @Type(Boolean) @Default(false) isDisabled!: boolean }
-
通过反射进行配置的存储和读取
这个在昨天的文章中有讲到一部分, 比如配置表单、表格、搜索框、权限 等
3. 再次强调面向对象
为了整个前端项目的工程化、结构化、高度抽象化,这里不得不再次强调面向对象的设计:)
-
这是个拼爹的社会
一些通用的功能,一旦有复用的可能, 都可以考虑和尝试让其父类进行实现, 如需要子类传入一些特性参数时, 可以使用抽象方法或抽象属性(这可是Java中没有的)来传入父类实现过程中需要的特性参数。
-
合理的抽象分层
将一些特性按照不同的抽象概念进行组合与抽离,实现每个类的功能都是尽可能不耦合,实现类的单一职责。如存在多继承, 在考虑实现类的实现成本前提下,可考虑抽象到接口
interface
中。 -
还有很多,有空再一一列举
4. 严格但又有趣的 tsdoc
我们先来看一些注释的截图吧:)
一些详细的注释、弃用的方法、选填的参数、传入参数后可能影响或依赖的其他参数,在注释里写好玩的 emoji
或者图片,甚至是 直接在注释里写调用 demo
, 让调用方可以很轻松愉快的对接调用, 玩归玩, 确实对整体项目的质量有很大的帮助。
三、 写在最后
中午跟同事吃饭聊了聊现在国内大前端的一个状态, 当时聊到一个关键词 舒适区
, 还有前端整个技术栈过于灵活的一些优缺点, 几个大老爷们都发出了一些感慨, 如果前端能够更标准化一些, 像 Java
一样, 说不定前端还能上升几个高度。
我们基于今天文章里的一些设计写了一些DEMO,但目前不太方便直接开源,如果有兴趣,可以私聊我获取代码链接。
是的, 我还是那个 Java
仔, 是, 也不仅仅是。
That's all, 今天水的文章到此结束。