Files
Vue3Template/tsVue3Decorators/README.md
2024-09-27 00:58:46 +08:00

224 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# vue3decorators
注意这不是一个通用的注解包,这只是脚手架项目
> Vue3Template[https://github.com/helpcode/Vue3Template](https://github.com/helpcode/Vue3Template)
抽离出来的注解,因为每次在项目中使用的时候需要导入太多次,太麻烦。所以将注解处理出来,单独作为包。
部分注解只能在`Vue3Template`这个脚手架项目中使用,有的是注解通用的!
**欢迎使用 [Vue3Template](https://github.com/helpcode/Vue3Template) 来快速开发构建您的项目一起来感受Vue3+Typescript的魅力把..**
## 1: 安装
```
npm i --save-dev vue3decorators
```
## 2: 使用
```js
import { Injectable, Inject } from 'vue3decorators';
```
## 3: 已实现的注解
注意阅读下面内容的时候请参考 [Vue3Template](https://github.com/helpcode/Vue3Template) 项目来对照看,[Vue3Template](https://github.com/helpcode/Vue3Template) 源码中有更详细的使用和注释!
### 1@Directive()
本注解主要在文件 `directive/index.directive.ts`的类`DirectiveList`中使用,加在类`DirectiveList`的方法上让方法成为Vue的自定义指令方法名就是指令名。例如方法`public index() {}`那么Vue组件中指令则为`v-index`
示例:
```js
# 文件directive/index.directive.ts
import { Directive } from 'vue3decorators';
export class DirectiveList {
@Directive()
public index() {
return {
bind: (el: Element, binding: VNodeDirective, vnode: VNode) => {
// console.log(el)
// console.log(binding)
console.log("v-index 指令接收到的数值:", binding.value);
// console.log(vnode);
}
}
}
}
```
Vue组件中使用
```pug
h2(v-index='200') {{title}}
```
### 2@Injectable()@Inject() 依赖注入
注解`@Injectable()`加在类,主要作用是收集依赖,而`@Inject()`加在类的属性上,会把`@Injectable()`的类注入到属性上。
示例:
```js
import { Injectable, Inject } from 'vue3decorators';
@Injectable()
class Demo1 {
public hello: string = "我是Demo1类"
}
class Demo2 {
@Inject()
public test!: Demo1;
public GetTest(): string {
return this.test.hello // 返回:"我是Demo1类"
}
}
```
### 3@GET、@POST、@PUT、@DELETE
主要在文件 `service/impl` 中使用,加在类的方法上,注解不需要参数。遵守约定:
被注解的方法名和`index.config.ts``ApiList` 的key名称一样即可。
设计思路:
- 1: `index.dao.ts` 的类 `Axios` 上有注解 `@Injectable()`,当程序通过`init.run.ts`运行的时候,注解`@Injectable()`会将类给存储到公共数组中。
- 2: 然后在使用注解`@Inject()`的时候会从数组中将`axios`取出来,然后进行 `new axios()` 实例化,之后保存到专门的`Model`中存放。
- 3: 当用户在使用`@GET``@POST``@PUT``@DELETE`这些注解的时候,这些注解会从`Model`取出`axios`的实例,然后调用 `axios`类中的方法进行网络请求。
- 4: 请求到的数据会作为`@GET``@POST``@PUT``@DELETE`这些注解所注解方法的返回值,直接返回给方法调用者
设计的原因:
注解内部会自动保存并调用,用户配置好的`Axios`实例!而不是使用注解内置自己配置的`Axios`,如果使用注解自身的那么会导致用户的一些自定义请求拦截,自定义请求基地址,自定义请求头都不存在。所以这边注解内部必须使用用户配置好的实例,把自由权交给使用者...
示例:
```js
import { HomeService } from "../Home.service";
import { GET, POST, GlobalMethod } from 'vue3decorators';
class HomeServiceImpl implements HomeService {
/**
* @GET 被打上这些注解的Service可以在Vue组件中使用。
* 1: 方法内部不需要任何的处理逻辑,留空即可。
* 2: 方法调用的时候只接受请求需要的参数
* 3: 现在V3版本的注解例如@GET()是不需要传入请求地址参数的方法名就是接口地址的key名称
* 例如index.config.ts 中 ApiList 的key名称
* {
* DevUrl: 'http://localhost:9000',
* ProdUrl: 'http://127.0.0.1:3000',
* ApiList: {
* index: '/test',
* haha: '/haha'
* },
* }
* 这里的key名称indexhaha直接作为 ServiceImpl 的方法名即可。
* 注解内部会自动去根据方法名,例如 index 去寻找 ApiList 下的key从而拿到请求地址 /test
* 然后注解会自动调用用户配置好的Axios来发送请求注意请求处理的所有逻辑交给用户。注解只负责
* 调用用户配置好的Axios而已。请求成功后注解会自动调用被注解的方法然后直接将数据返回给Vue组
* 件调用者,这也就是这里为什么方法内部不需要处理逻辑的原因。因为一切都在注解内部实现,并遵守
* 约定大于配置 的原则。
* @param data object 请求参数
*/
@GET()
public async index(data: object): Promise<any> {}
@POST()
public async haha(data: object): Promise<any> {}
}
```
Vue组件中调用
```vue
<template lang="pug">
// .....
</template>
<script lang="ts">
import HomeServiceImpl from '@impl/home.service.impl'
export default createComponent({
setup(props: PropOptions, ctx: SetupContext) {
onMounted(async ()=> {
let data = await HomeServiceImpl.index({ id: 1,page: 1 });
console.log("ajax请求到的数据为", data)
})
}
})
</script>
<style lang="stylus" scoped>
// .....
</style>
```
### 4@Mixin()
主要在文件 `mixin/index.mixin.ts` 中使用加在类的方法上会让类的方法自动成为Vue的全局mixin。
示例:
```js
@Injectable()
export class MixinList {
@Mixin()
public Router() {
return {
beforeCreate: setRuntimeVM
}
}
}
```
### 5@GlobalMethod()
`@GlobalMethod()`可以随意加在类的方法上,不过个人推荐加在`utils/`文件夹的类的方法上。类的方法一旦被加上这个注解那么这个方法将成为全局方法,可以在`Vue`组件中直接是使用,注意组件内调用的时候是:`$方法名()`,之所以加上`$`是为了防止和组件内方法名冲突!!
示例:
```js
export class Utils {
/**
* 动态设置网页title
* @param title
*/
@GlobalMethod()
public setTitle(title: string): void {
document.title = title;
}
}
```
Vue组件中调用
```vue
<template lang="pug">
// .....
</template>
<script lang="ts">
export default createComponent({
setup(props: PropOptions, ctx: SetupContext) {
onMounted(async ()=> {
console.log("全部方法:", (ctx.root as any).$setTitle("测试"));
})
}
})
</script>
<style lang="stylus" scoped>
// .....
</style>
```