ts 装饰器

这篇具有很好参考价值的文章主要介绍了ts 装饰器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 使用装饰器前,需要把 tsconfig.json 中 experimentalDecorators 设置为 true
  • 学习了小满的B站课程:https://www.bilibili.com/video/BV1wR4y1377K?p=24

前言

ts中有几种装饰器类型:

  • 类装饰器 ClassDecorator
  • 方法装饰器 MethodDecorator
  • 参数装饰器 ParameterDecorator
  • 属性装饰器 PropertyDecorator

一、类装饰器 ClassDecorator

  • 功能 & 使用场景:不想破坏原有的类的结构,又不想去读内部的代码逻辑,只想 给类增加一些新的属性或方法,可对该类使用装饰器
  • 装饰器需要定义为 ClassDecorator 类型
  • 装饰器回传参数 target, 是调用者的 构造函数
  • 两种使用方式:
    • 在 class 前 @DecoratorName
    • 在 class 后 DecoratorName(className)

1、类装饰器的简单使用

const DecoratorClassDemo: ClassDecorator = (target) => {
  // 回传的 target 是调用者的构造函数
  // 可以额外定义属性、方法
  target.prototype.color = 'blue'
  target.prototype.showColor = () => {
    console.log('哈哈哈哈')
  }
}

// 写法一:若担心浏览器不支持,可以使用写法二
@DecoratorClassDemo
class Http {
  // 不想读里面的逻辑,又想加一些东西,并且不破坏原有的结构,可以考虑在外层使用装饰器
}
// 写法二:
// DecoratorClassDemo(Http)

// 将类实例化后,可以访问到装饰器里新增的属性和方法
const http = new Http() as any
console.log('http.color', http.color) // blue
http.showColor()

如果想要 传参数 给类装饰器,怎么做?

2、装饰器工厂

可以先把它定义为 普通函数(保证参数的接收),然后在其 内部返回一个装饰器函数 即可(闭包)

// 可以先把它定义为普通函数(保证参数的接收),然后在其内部返回一个装饰器函数即可
const DecoratorClassDemo2 = (msg: string, age: number) => {
  const fn: ClassDecorator = (target) => {
    target.prototype.msg = msg
    target.prototype.age = age
  }
  return fn
}
@DecoratorClassDemo2('hahaha', 18)
class Http2 {
  // .....
}
const http2 = new Http2() as any
console.log('类装饰器传参---', http2.msg)
console.log('类装饰器传参---', http2.age)

同样的方式在其他装饰器中也有使用

二、方法装饰器 MethodDecorator

  • 顾名思义,就是对 方法 使用装饰器,在方法前 @DecoratorName
  • 方法装饰器需要声明为 MethodDecorator 类型
  • 方法装饰器回传参数:target, propertyKey, descriptor
    • target:调用者的 原型
    • propertyKey: 调用者的 key,即 方法名称
    • descriptor:调用者的 描述
  • 方法装饰器 想要 回调数据给调用者,需要 把 descriptor 声明为 PropertyDescriptor 类型,通过 descriptor.value 返回

例:写一个简单的Get请求装饰器

// 安装:npm i axios 
import axios from 'axios'

const Get = (url: string) => {
  // 这里注意把 descriptor 定义为 PropertyDescriptor 类型
  const fn: MethodDecorator = (target, propertyKey, descriptor: PropertyDescriptor) => {
    // 【target】:{constructor: ƒ, getList: ƒ}
    // 【propertyKey】:getList
    // 【descriptor】:{writable: true, enumerable: false, configurable: true, value: ƒ}

    axios.get(url).then(res => {
      // 拿到结果后通过 descriptor 的 value 返回(注意value是个函数)
      descriptor.value(res.data) 
    })
  }
  return fn
}

class Http3 {
  // 对 getList  使用 方法装饰器 Get
  @Get('https://api.apiopen.top/api/getHaoKanVideo?page=1&size=10')
  getList (data: any) {
    console.log(data)
  }
}

最终打印出的 data:

ts 装饰器

三、参数装饰器 ParameterDecorator

  • 顾名思义,对 参数 使用装饰器,在参数前 @DecoratorName
  • 参数装饰器需要定义为 ParameterDecorator 类型
  • 参数装饰器回传参数: target, propertyKey, parameterIndex
    • target:调用者的 原型
    • propertyKey:调用者的 方法名称
    • parameterIndex:该参数是方法中的 第几个参数
  • 需要用到插件 reflect-metadata使用元数据
    • 安装命令: npm i reflect-metadata
    • tsconfig.json 中需要将 emitDecoratorMetadata 开启
    • Reflect.defineMetadata存入元数据,参数如下:
      • metadataKey: 所要存元数据的 key
      • metadataValue: 对应的 value
      • target: 存入的 目标
    • Reflect.getMetadata取出元数据,参数如下:
      • metadataKey:所要取的元数据的 key
      • target:所要取的 目标

在上面的基础上继续造例子,将 参数data 处理为优先返回内部的 result

import axios from 'axios'
import 'reflect-metadata'

const Result = () => {
  const fn: ParameterDecorator = (target, propertyKey, parameterIndex) => {
    // 【target】:{constructor: ƒ, getList: ƒ} 
    // 【propertyKey】:getList 
    // 【parameterIndex】:0
    
    // 存入数据:key='result'
    Reflect.defineMetadata('key', 'result', target)
  }
  return fn
}


const Get2 = (url: string) => {
  const fn: MethodDecorator = (target, propertyKey, descriptor: PropertyDescriptor) => {
    axios.get(url).then(res => {
      // 在这里取出所存元数据的 key 所存的 value(字符串 result) ,看返回的数据中有没有这个值,有的话直接返回
      const k = Reflect.getMetadata('key', target)
      
      descriptor.value(k ? res.data[k] : res.data)
    })
  }
  return fn
}
class Http4 {
  @Get2('https://api.apiopen.top/api/getHaoKanVideo?page=1&size=10')

  // 比如:对这里的 参数data 使用装饰器 Result,目的是自动取出 data 中的 result 属性
  // @Result 优先于 @Get2 先执行,在 @Result 存元数据,在 @Get2 中取元数据
  getList(@Result() data: any) {
    console.log(data)
  }
}

经过参数装饰器后,打印出的 data:

ts 装饰器

四、属性装饰器 PropertyDecorator

  • 属性 的装饰器,在属性前 @DecoratorName
  • 属性装饰器需要定义为 PropertyDecorator 类型
  • 属性装饰器回传参数:target, propertyKey
    • target:调用者的 原型
    • propertyKey: 调用者的 属性名字
const Color: PropertyDecorator = (target, propertyKey) => {
  // 【target】:{constructor: ƒ} 
  // 【propertyKey】:color
  
  // 一些操作...
}
class Http5 {
  // 对 属性color 使用 属性装饰器Color
  @Color
  color:string
  constructor () {
    this.color = 'blue'
  }
}

看的时候很懵逼,一定要多敲才能理解深刻!!

如果只看文章太痛苦,可以看文章最上面引言中提到的B站视频教程,然后再敲一遍文章来源地址https://www.toymoban.com/news/detail-476387.html

到了这里,关于ts 装饰器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Cannot find base config file @vue/tsconfig/tsconfig.web.json

    vue升级到最新版本,node18 会出现warning 参考issues Cannot find base config file @vue/tsconfig/tsconfig.web.json

    2024年02月12日
    浏览(40)
  • 使用TS装饰器从0封装一个socket.io服务器

            最近沉迷WebRTC技术,想用WebRTC试做一个快启动的文件传输PWA应用。涉及到使用websocket服务器传输WebRTC的信令,全栈的话自然是选择Nodejs做服务器了。         因为项目体量肯定不是很大,所以所有选型都以高性能轻量为主要目标。前端选择的是solidjs+tailwindcss,后端

    2024年02月08日
    浏览(28)
  • 【制作npm包3】了解 tsconfig.json 相关配置

    本文是系列文章, 作者一个橙子pro,本系列文章大纲如下。转载或者商业修改必须注明文章出处 一、申请npm账号、个人包和组织包区别 二、了解 package.json 相关配置 三、 了解 tsconfig.json 相关配置 四、 api-extractor 学习 五、 npm 包制作完整教程,我的第一个npm包 在最早的 ty

    2024年02月12日
    浏览(43)
  • 面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?

    面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们? 在TypeScript中,装饰器( Decorators )是一种用于增强代码功能的特殊类型声明。装饰器提供了一种在类、方法、属性等代码元素上注释或修改的方式,使得我们可以通过装饰器来扩展、修改或监视代码的

    2024年02月15日
    浏览(56)
  • 【TypeScript】tsconfig.json文件到底是干啥的?作用是什么?

    参考学习博文: 掌握tsconfig.json 一、tsconfig.json简介 1、tsconfig.json是什么? TypeScript 使用 tsconfig.json 文件作为其 配置文件 ,当一个目录中存在 tsconfig.json 文件,则认为该目录为 TypeScript 项目的 根目录 。 通常 tsconfig.json 文件主要包含两部分内容: 指定待编译文件 定义编译选

    2024年02月01日
    浏览(45)
  • 解决Vscode报错 [Vetur can‘t find ‘tsconfig.json‘ or ‘jsconfig.json‘]

    翻译一下报错信息,\\\" Vetur找不到tsconfig.json文件或者jsconfig.json文件\\\". 首先Vetur只会扫描项目的根目录下的jsconfig或者tsconfig,如果没有这两个文件之一,就会报错. 如果你是通过vue-cli创建的vue项目,默认都会有jsconfig或者tsconfig,那问题极有可能是打开项目文件夹的时候路径不对: 以下

    2024年03月15日
    浏览(38)
  • 解决vscode中导入的vue项目tsconfig.json文件首行标红问题

    vscode中导入的vue项目 tsconfig.json文件标红,文件中第一行 { 处标红 项目中自定义的tsconfig.json文件与vscode本身会自动进行 JavaScript 的语义检查发生冲突,而tsconfig.json文件无法覆盖vscode本身的javascript检查,故标红 让项目自定义的tsconfig.json文件覆盖vscode自带的javascript语义检查

    2024年01月19日
    浏览(43)
  • vue项目的Husky、env、editorconfig、eslintrc、tsconfig.json配置文件小聊

    1、 Husky Husky 是一款管理 git hooks 的工具,可以帮助我们触发 git 提交的各个阶段: pre-commit、commit-msg、pre-push , 有助于我们在项目开发中的git规范和团队协作。 .husky 文件通常包含以下内容: pre-commit :在提交代码前运行的脚本,可以用于代码格式化、代码检查等操作; pr

    2024年04月28日
    浏览(28)
  • 学习ts(十)装饰器

    装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上,是一种在不改变原类和使用继承的情况下,动态的扩展对象功能。 装饰器使用 @expression 形式,其中 expression 必须评估为一个函数,该函数将在运行时调用,并带有有关装饰声明的信息。

    2024年02月10日
    浏览(37)
  • ts 装饰器

    使用装饰器前,需要把 tsconfig.json 中 experimentalDecorators 设置为 true 学习了小满的B站课程:https://www.bilibili.com/video/BV1wR4y1377K?p=24 ts中有几种装饰器类型: 类装饰器 ClassDecorator 方法装饰器 MethodDecorator 参数装饰器 ParameterDecorator 属性装饰器 PropertyDecorator 功能 使用场景: 不想破坏

    2024年02月08日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包