30.【TypeScript 教程】Reflect Metadata

TypeScript Reflect Metadata

本节介绍的 Reflect Metadata 主要用来在声明的时候添加和读取元数据。通过这种方式给对象添加额外的信息,是不会影响对象的结构的。

1. 解释

Reflect,翻译为『反射』,Metadata,翻译为『元数据』。反射这个概念在 Java 等众多语言中已经广泛运用,Reflect Metadata 就是通过装饰器来给类添加一些自定义的信息,然后通过反射将这些信息提取出来,也可以通过反射来添加这些信息。

2. 安装使用

通过 npm 安装这个库:

npm i reflect-metadata --save

而且需要在 tsconfig.json 中配置:

{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

命令行使用:

tsc --target ES5 --experimentalDecorators --emitDecoratorMetadata

当启用后,只要 reflect-metadata 库被引入了,设计阶段添加的类型信息可以在运行时使用。

import 'reflect-metadata'

@Reflect.metadata('token', 'aW1vb2M=')
class Employee {

  @Reflect.metadata('level', 'D2')
  salary() {
    console.log('这是个秘密')
  }

  @Reflect.metadata('times', 'daily')
  static meeting() {}

}

const token = Reflect.getMetadata('token', Employee)
const level = Reflect.getMetadata('level', new Employee(), 'salary')
const times = Reflect.getMetadata('times', Employee, 'meeting')

console.log(token) // aW1vb2M=
console.log(level) // D2
console.log(times) // daily

TIPS: 注意, 实例方法与静态方法取元数据是不同的,实例方法需要在类的实例上取元数据,静态方法直接在类上取元数据。

3. API

import 'reflect-metadata'
 
// 元数据的命令式定义,定义对象或属性的元数据
Reflect.defineMetadata(metadataKey, metadataValue, target)
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey)
 
// 检查对象或属性的原型链上是否存在元数据键
let result = Reflect.hasMetadata(metadataKey, target)
let result = Reflect.hasMetadata(metadataKey, target, propertyKey)
 
// 检查对象或属性是否存在自己的元数据键
let result = Reflect.hasMetadata(metadataKey, target)
let result = Reflect.hasMetadata(metadataKey, target, propertyKey)
 
// 获取对象或属性原型链上元数据键的元数据值
let result = Reflect.getMetadata(metadataKey, target)
let result = Reflect.getMetadata(metadataKey, target, propertyKey)
 
// 获取对象或属性的自己的元数据键的元数据值
let result = Reflect.getOwnMetadata(metadataKey, target)
let result = Reflect.getOwnMetadata(metadataKey, target, propertyKey)
 
// 获取对象或属性原型链上的所有元数据键
let result = Reflect.getMetadataKeys(target)
let result = Reflect.getMetadataKeys(target, propertyKey)
 
// 获取对象或属性的所有自己的元数据键
let result = Reflect.getOwnMetadataKeys(target)
let result = Reflect.getOwnMetadataKeys(target, propertyKey)
 
// 从对象或属性中删除元数据
let result = Reflect.deleteMetadata(metadataKey, target)
let result = Reflect.deleteMetadata(metadataKey, target, propertyKey)
 
// 通过装饰器将元数据应用于构造函数
@Reflect.metadata(metadataKey, metadataValue)
class C {
  // 通过装饰器将元数据应用于方法(属性)
  @Reflect.metadata(metadataKey, metadataValue)
  method() {
  }
}

4. 结合装饰器使用

Reflect Metadata 结合上节介绍的装饰器:

import 'reflect-metadata'

function get(path: string): MethodDecorator {
  return (target, name) => {
    Reflect.defineMetadata('path', path, target, name)
  }
}

class Employee {
  @get('/init')
  async init() {}
}

const metadata = Reflect.getMetadata('path', new Employee(), 'init')
console.log(metadata) // '/init'

解释: 如果经常开发 Node.js 的同学对这样的写法是不是有些熟悉呢?类方法 init() 上的装饰器 get() 传入元数据 '/init',再通过反射拿到这个路由信息,将这些路由信息进行一定的封装,然后绑定在 koa-router 上,就能达到自动加载路由的功能。

5. 小结

本节介绍了 Reflect Metadata 的一些基础使用方式,一些基础库源码如 vue-class-componentAngular 均使用了 Reflect Metadata ,有兴趣的可以深入源码学习下。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. Vue 3相对于Vue 2的优势主要包括: - 更小的体积:Vue 3对内部代码进行了重构,采用了更好的编译优化和摇树优化,使得打包后的体积更小。 - 更好的性能:Vue 3引入了Proxy代理对象,替代了Vue 2中的Object.defineProperty,使得响应式系统的性能得到了大幅提升。 - 更好的类型推导:Vue 3使用了TypeScript进行重写,提供了更好的类型推导支持,使得开发者在编写代码时能够更加准确地获取类型推断。 - 更好的组合API:Vue 3引入了Composition API,使得组件逻辑可以更好地组织和复用,而不再依赖于Options API。 - 更好的逻辑复用:Composition API的引入使得逻辑复用更加容易,开发者可以将逻辑提取为独立的函数,并在多个组件中进行共享。 2. Vue 3的响应式原理与Vue 2有所不同。在Vue 2中,通过Object.defineProperty来实现数据劫持和观察,从而实现响应式。而在Vue 3中,使用了Proxy代理对象来实现响应式。 Proxy代理对象可以监听对象上的操作,并在发生改变时触发相应的行为。Vue 3中使用Proxy对象来监听组件的数据变化,并通过触发相应的更新操作来实现响应式。相比于Vue 2的Object.defineProperty,Proxy具有更好的性能和更灵活的API。 3. Vue 3的一些新特性包括: - Composition API:提供了更好的逻辑组织和复用方式,使得代码更加清晰和可维护。 - Fragments:可以在组件中使用多个根元素,而不再需要一个根元素包裹。 - Teleport:可以将组件的内容渲染到DOM中的任意位置。 - Suspense:用于处理异步组件的加载状态,可以在加载完成前展示占位内容。 - 其他一些性能优化和语法糖改进。 4. Vue 3的生命周期相比Vue 2有所变化。Vue 3中的生命周期钩子函数有以下几个: - beforeCreate:在实例初始化之前被调用。 - created:在实例创建完成后被调用,可以访问到data、methods等选项。 - beforeMount:在挂载开始之前被调用。 - mounted:在挂载完成后被调用,可以访问到DOM元素。 - beforeUpdate:在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前。 - updated:在数据更新之后被调用,发生在虚拟DOM重新渲染和打补丁之后。 - beforeUnmount:在卸载组件之前被调用。 - unmounted:在卸载组件之后被调用。 5. Vue 3中可以使用自定义hooks来实现逻辑的复用。自定义hooks是一个函数,可以在组件中调用,并且可以在多个组件中共享逻辑。 自定义hooks可以通过组合API的方式来实现。可以将一些逻辑提取为独立的函数,然后在不同的组件中调用这些函数,从而实现逻辑的复用。 6. TypeScript是一种静态类型检查的JavaScript超集。它为JavaScript添加了类型注解和一些新的语法特性,以提供更好的代码提示、类型检查和重构支持。 7. TypeScript提供了多种数据类型,包括基本类型(如number、string、boolean等)、对象类型(如object、array等)、函数类型、元组类型、枚举类型等。 8. TypeScript中的函数可以指定参数类型、返回值类型,并且支持可选参数和默认参数。函数类型可以通过箭头函数表达式或function关键字进行定义。 9. 在TypeScript中,类可以通过class关键字进行定义。类可以包含属性、方法和构造函数,并且可以继承其他类或实现接口。 10. Yarn是一个替代npm的包管理工具。它具有更快的安装速度和更好的缓存机制,可以提高项目的构建效率。 安装Yarn可以通过npm全局安装命令进行安装:npm install -g yarn 使用Yarn可以通过yarn install命令安装项目依赖,通过yarn add命令添加新的依赖,通过yarn remove命令移除依赖,通过yarn start命令运行项目等。 11. 在Vue 3中使用TypeScript可以通过以下步骤快速使用和封装: - 创建一个Vue 3的TypeScript项目 - 在组件中使用TypeScript的类型注解来声明props、data、computed等属性的类型 - 使用Composition API来组织和复用逻辑 - 在Vue 3的模板中使用TypeScript的语法和表达式进行数据绑定和渲染 - 封装可复用的组件时,可以使用TypeScript的接口来定义props的类型和事件的类型,以提供更好的类型检查和代码提示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红薯不甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值