一、前言
装饰器是ES2016提出来的一个提案,当前处于Stage 2阶段,通过本文学习,你将学到以下内容:
- 了解什么是装饰器
- 在
class中使用装饰器 - 在方法使用装饰器
- 在
Vue中使用装饰器 - 装饰器与注释的区别
二、什么是装饰器
装饰器是一种与类相关的语法糖,用来包装或者修改类或者类的方法的行为,其实装饰器就是设计模式中装饰者模式的一种实现方式。
三、装饰器分类
按照装饰器被装饰的特性来分,一共可以分为以下五种类:类装饰器、方法装饰器、属性装饰器、方法装饰器、访问符装饰器
3.1 类装饰器 Class Decorator
类装饰器在类声明之前被声明(紧靠着类声明),类装饰器可以拦截类的构造函数 constructor,这使得我们可以通过结合传入的 metadata,以此确定类在运行时是如何被处理、实例化以及使用的。
- 类的装饰器有一个参数,为类的构造函数,通过这个参数可以改变类上的属性方法等
- 类的装饰器会在类定义后执行,不需要类实例化
3.2 属性装饰器 Property Decorator
属性装饰器声明在一个属性声明之前(紧靠着属性声明),我们可以使用它来劫持属性的 getter 和 setter。
3.3 方法装饰器 Method Decorator
方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。
3.4 参数装饰器 Parameter Decorator
参数装饰器声明在一个参数声明之前(紧靠着参数声明)。 参数装饰器应用于类构造函数或方法声明,但参数装饰器的返回值会被忽略。
3.5 访问符装饰器 Accessor Decorator
访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。访问器装饰器应用于访问器的 属性描述符并且可以用来监视,修改或替换一个访问器的定义。访问器装饰器不能用在声明文件中(.d.ts),或者任何外部上下文(比如 declare 的类)里。
四、 Vue中使用装饰器
vue-class-component是vue作者尤大推出的一个支持使用class方式来开发vue单文件组件的库。在Vue2.0中使用TypeScript语法时,需要引用 vue-property-decorator,且完全依赖于vue-class-component,有几个装饰器和 1 个函数 (Mixin)
@Prop@PropSync@Model@ModelSync@Watch@Provide@Inject@ProvideReactive@InjectReactive@Emit@Ref@VModel@Component(由 vue-class-component 提供)Mixins(mixins由 vue-class-component提供的名为 helper 函数)
4.1 @Prop
我们在使用Vue时有时会遇到子组件接收父组件传递来的参数.我们需要定义Prop属性.
ES6写法
export default {
props: {
propA: {
type: Number
},
propB: {
default: 'default value'
},
propC: {
type: [String, Boolean]
},
}
}
当我们在
vue单文件中使用TypeScript时,引入vue-property-decorator之后,使用@Prop
<script lang="ts">
import {Vue, Component, Prop} from 'vue-property-decorator';
@Component({})
export default class "组件名" extends Vue{
@Prop(Number) propA!: number;
@Prop({default: 'default value'}) propB!: string;
@propC([String, Boolean]) propC: string | boolean;
}
</script>
总结:
@Prop接受一个参数可以是类型变量或者对象或者数组.@Prop接受的类型比如Number是JavaScript的类型,之后定义的属性类型则是TypeScript的类型
4.2 @PropSync
4.3 @Model
4.4 @ModelSync
4.5 @Watch
4.6 @Provide
4.7 @Inject
4.8 @ProvideReactive
4.9 @InjectReactive
4.10 @Emit
4.11 @Ref
4.12 @VModel
4.13 @Component
4.14 Mixins
在使用Vue进行开发时我们经常要用到混合
ES6写法
// 定义要混合的类pagination.js
export default {
data() {
return {
pagination: {
page: 1,
pageSize: 10,
total: 0,
showTotal: (total, range) => `共 ${total} 条`
},
// requestData: {
// page: this.pagination.page,
// pageSize: this.pagination.pageSize,
// },
}
},
computed:{
requestData(){
return {
page: this.pagination.page,
pageSize: this.pagination.pageSize,
};
}
},
methods: {
init() {
},
search() {
},
pageChange(page) {
this.pagination.page = page;
this.requestData.page = page.current;
this.search();
}
}
}
// 引入
<script>
import pagination from "@/mixins/pagination";
export default {
components: {},
mixins: [pagination],
data() {
return {
columns
},
created() {
this.init();
},
methods: {
init(){
let app = this;
app.loading = true;
list(app.requestData).then(res=>{
app.dataSource = res.data.list;
app.pagination.total = res.data.total;
app.authList = [];
res.data.authList.forEach(function (v) {
const obj = {
label: v.title,
value: v.id
};
app.authList.push(obj);
});
app.loading = false;
})
},
}
}
</script>
当我们在
vue单文件中使用TypeScript时,引入vue-property-decorator之后,使用mixins之后我们有两种mixins的方法
vue-class-component
// 定义要混合的类 mixins.ts
import Vue from 'vue';
import Component from 'vue-class-component';
@Component // 一定要用Component修饰
export default class myMixins extends Vue {
value: string = "Hello"
}
// 引入
import Component {mixins} from 'vue-class-component';
import myMixins from 'mixins.ts';
@Component
export class myComponent extends mixins(myMixins) {
// 直接extends myMinxins 也可以正常运行
created(){
console.log(this.value) // => Hello
}
}