运行环境
装饰器是一项实验性特性,需要在tsconfig.json或tsconfig.app.json中开启配置
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
整体架构流程
- services 封装的axois服务文件
- decorator 装饰器文件
- api文件
- 页面文件
例如:
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。
request.ts
封装axios
import axios from 'axios'
const axiosInstance = axios.create({
timeout: 10000,
baseURL: ''
})
// 请求拦截
axiosInstance.interceptors.request.use((config) => {
return config
})
// 响应拦截
axiosInstance.interceptors.response.use(
(response) => {
const { data } = response
return data
},
(err) => err
)
interface RequestConfig {
method: string,
url: string,
data: any
}
const request = (config: RequestConfig) => {
const { method, url, data } = config
return axiosInstance({ method, url, data })
}
const get = (url: string, params: any) => {
return request({
method: 'get',
url,
...params
})
}
const post = (url: string, params: any) => {
return request({
method: 'post',
url,
...params
})
}
export {
get,
post
}
decorator.ts
这里封装了3个修饰器,除了常规的Get 和 Post 请求,还额外加了Result,对返回值格式的处理
1. 方法装饰器(MethodDecorator)
方法装饰器参数有三个,target,key descriptor
- target: 被装饰的类的实例
- key: 被装饰的属性名称
- descriptor: 被装饰属性的属性描述符
2.参数装饰器(ParameterDecorator)
参数装饰器参数有三个,target,methodName ,index
- target: 被装饰的类的实例
- methodName : 被装饰的方法名
- index: 被装饰的参数在函数的参数列表中的索引位置
import 'reflect-metadata'
import { get, post } from '@/services/axiosInstance'
export const Get = (url: string) => {
const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = (...args: any) => {
const params = args[0]
const key: string = Reflect.getMetadata('key', target)
return get(url, params).then((res: any) => {
return originalMethod.call(this, res[key])
})
}
}
return fn
}
export const Post = (url: string) => {
const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = (...args: any) => {
const params = args[0]
const key: string = Reflect.getMetadata('key', target)
return post(url, params).then((res: any) => {
return originalMethod.call(this, res[key])
})
}
}
return fn
}
export const Result = () => {
const fn: ParameterDecorator = (target) => {
Reflect.defineMetadata('key', 'data', target)
}
return fn
}
api.service.ts
使用修饰器
import { Get, Result } from '@/decorator'
class UserApi {
@Get('/getUserApi')
getUserInfoApi(@Result() data: any) {
return data
}
}
export default UserApi
index.service.ts
import $UserApi from './userApi'
export default {
$UserApi: new $UserApi()
}
home.vue
import UserApi from '@/services'
import { onMounted } from 'vue'
const { $UserApi } = UserApi
const getUserInfo = () => {
$UserApi.getUserInfoApi({}).then((res: any) => {
console.log(res)
})
}
onMounted(() => {
getUserInfo()
})