Skip to content

Commit

Permalink
6-ts装饰器示例
Browse files Browse the repository at this point in the history
  • Loading branch information
Duanzihuang committed Jul 16, 2020
1 parent e24c808 commit ac170b5
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ import App from './App.vue'
import router from './router'
import store from './store'

// 以下为测试ts相关的代码
// import '@/ts/decorator3'

createApp(App).use(router).use(store).mount('#app')
66 changes: 66 additions & 0 deletions src/ts/decorator1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* 装饰器:本质是一个方法,可以注入到类、方法、属性参数上来拓展类、属性、方法、参数的功能
*
* 分类:类装饰器、属性装饰器、方法装饰器、方法参数装饰器
*
* 类装饰器: 在不修改当前类的前提下,动态给类添加属性和方法
*
* 装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)
*
* 各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器
* 如果每种有多个,则从后往前执行
*/

// 普通装饰器(无法传参)
function Log(target: any) {
// console.log(target)
// target 代表当前类

target.prototype.apiUrl = 'http://www.api.com'

target.prototype.send = function() {
console.log(`send invoke`)
}
}

// 装饰器工厂(可传参)
function LogFactory(params: any) {
return function(target: any) {
// console.log(target)
// console.log('------')
// console.log(params)
target.prototype.apiUrl = params.apiUrl
}
}

// 普通装饰器(重写构造器方法或是其它方法)
function LogOverride(target: any) {
return class extends target {
apiUrl = 'http://api.duanzihuang.top'

getData() {
console.log('重写后的apiUrl:', this.apiUrl)
}
}
}

//@Log //普通装饰器(无法传参)
// @LogFactory({apiUrl: 'http://api.huangjiangjun.top'})
@LogOverride
class HttpClient {
public apiUrl: string | undefined

constructor() {
this.apiUrl = 'http://api.huangjiangjun.top'
}

getData() {
console.log(this.apiUrl)
}
}

const httpClient: any = new HttpClient()
httpClient.getData()
// console.log(httpClient)
// console.log(httpClient.apiUrl)
// httpClient.send()
34 changes: 34 additions & 0 deletions src/ts/decorator2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* 装饰器:本质是一个方法,可以注入到类、方法、属性参数上来拓展类、属性、方法、参数的功能
*
* 分类:类装饰器、属性装饰器、方法装饰器、方法参数装饰器
*
* 属性装饰器:
* 接收两个参数: 参数1 类的构造函数(静态成员)/原型对象(实例成员)
* 参数2 成员的名字
*
* 装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)
*
* 各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器
* 如果每种有多个,则从后往前执行
*/

function Property(params: string) {
// 参数1 类的构造函数(静态成员)/原型对象(实例成员) prototype === HttpClient2.prototype
// 参数2 成员的名字
return function(prototype: any, name: string) {
prototype[name] = params
}
}

class HttpClient2 {
@Property('http://api.duanzihuang.top')
public apiUrl: string | undefined

getData() {
console.log('apiUrl is ', this.apiUrl)
}
}

const httpClient2 = new HttpClient2()
httpClient2.getData()
80 changes: 80 additions & 0 deletions src/ts/decorator3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* 装饰器:本质是一个方法,可以注入到类、方法、属性参数上来拓展类、属性、方法、参数的功能
*
* 分类:类装饰器、属性装饰器、方法装饰器、方法参数装饰器
*
* 方法装饰器:
* 接收三个参数: 参数1 类的构造函数(静态成员)/原型对象(实例成员)
* 参数2 方法的名字
* 参数3 方法描述
*
* 方法参数装饰器:
* 接收三个参数: 参数1 类的构造函数(静态成员)/原型对象(实例成员)
* 参数2 方法的名字
* 参数3 参数的索引
*
* 装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)
*
* 各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器
* 如果每种有多个,则从后往前执行
*/

// 方法装饰器
function Method(params: string) {
// 参数1 类的构造函数(静态成员)/原型对象(实例成员) prototype === HttpClient3.prototype
// 参数2 方法的名字
// 参数3 方法描述
return function(prototype: any, name: string, desc: any) {
// desc.value === getData
// console.log(desc)

// 保存之前的方法
const oldMethod = desc.value

desc.value = function(...args: any) {
args = args.map((item: any) => {
return String(item)
})

console.log('方法装饰器内部 ', args)

console.log('method invoke start -----', new Date() - 0)
oldMethod.apply(this, args)
console.log('method invoke end -----', new Date() - 0)
}
}
}

// 方法参数装饰器
function MethodParams(params: any) {
/**
* 参数1 类的构造函数(静态成员)/原型对象(实例成员)
* 参数2 方法的名字
* 参数3 参数的索引
*/
return function(prototype: any, name: string, index: number) {
console.log('---------------------------------------')
console.log(params)
console.log(prototype)
console.log(name)
console.log(index)
}
}

class HttpClient3 {
@Method('xxx')
getData(...args: any[]) {
console.log('getData method invoke', args)
}

setData(
@MethodParams('name') name: string,
@MethodParams('age') age: number
) {
console.log(`this person name is ${name} age is ${age}`)
}
}

const httpClient3 = new HttpClient3()
httpClient3.getData(123, 'nihao', true)
httpClient3.setData('段子黄', 31)

0 comments on commit ac170b5

Please sign in to comment.