Vue/Typescript 装饰器

TS 要想使用 Vue 组件得用 class,配合装饰器使用。

需要引用 vue-property-decorator


装饰器

@component

官方文档

js 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script lang="js">
export default {
name: 'Types',
data() {
return {
type: '-' // - 支出,+ 收入
}
},
methods: {
selectType(type) { // type 只能是 ‘-’ 或 ‘+’
if (type !== '-' && type !== '+') {
throw new Error('type is unknown')
}
this.type = type
}
},
};
</script>

ts 代码:

需要引入 vue-property-decorator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script lang="ts">
import Vue from 'vue';
import {Component} from 'vue-property-decorator';

@Component
export default class Types extends Vue {
type = '-';
selectType(type: string): void { // type 只能是 ‘-’ 或 ‘+’
if (type !== '-' && type !== '+') {
throw new Error('type is unknown');
}
this.type = type;
}
}
</script>

@Prop

官方文档

@Prop(options: (PropOptions | Constructor[] | Constructor) = {}) decorator

1
2
3
4
5
6
7
8
9
10
<script lang='ts'>
import { Vue, Component, Prop } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
@Prop(Number) readonly propA: number | undefined
@Prop({ default: 'default value' }) readonly propB!: string
@Prop([String, Boolean]) readonly propC: string | boolean | undefined
}
</script>

is equivalent to

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script lang='js'>
export default {
props: {
propA: {
type: Number,
},
propB: {
default: 'default value',
},
propC: {
type: [String, Boolean],
},
},
}
</script>

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script lang='ts'>
import Vue from 'vue';
import {Component} from 'vue-property-decorator';

@Component
export default class Types extends Vue {

@Prop(Number) xxx: number | undefined;
// Prop 告诉 Vue,xxx 不是 data 而是 prop
// Number 告诉 Vue,xxx 运行时是个 number
// xxx 是属性名
// number | undefined 告诉 TS xxx 的编译时类型
}
</script>

demo2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script lang="ts">
import Vue from 'vue';
import {Component, Prop} from 'vue-property-decorator';

@Component
export default class FormItem extends Vue {
@Prop({default: ''}) readonly value!: string;
@Prop({required: true}) fieldName!: string;
@Prop() placeholder?: string;

onValueChange(value: string): void {
this.$emit('update:value', value);
}
}
</script>

Vue 组件的三种方式(单文件组件)

  1. 用 JS 对象

    1
    export default { data, props, methods, created, ...}
  2. 用 TS 类 <script lang="ts">

    1
    2
    3
    4
    5
    @Component
    export default class XXX extends Vue{
    xxx: string = 'hello';
    @Prop(Number) xxx: number | undefined;
    }
  3. 用 JS 类 <script lang="js">

    1
    2
    3
    4
    @Component
    export default class XXX extends Vue{
    xxx = 'hi'
    }