224 lines
6.9 KiB
Markdown
224 lines
6.9 KiB
Markdown
# 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名称:index,haha,直接作为 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>
|
||
``` |