vue-property-decorator初探
公司旧版系统代码中使用了ts,而用ts写vue就用到了装饰器等一系列功能。
因此,对于装饰器进行了了解和学习。并进行了大致的总结。
什么是装饰器?
装饰器的作用是什么?
装饰器可以不修改已经写好的代码,去动态的添加相关的属性和方法。
比如说,给一个类已经写好了方法和属性。但是在不同的文件中使用这个类需要增加特定的方法。
我们就可以通过装饰器来实现这个功能。@name 即为使用装饰器的方法。其中target函数就是要装饰的目标。
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
行为等同于:
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
如果想要传递参数,可以在装饰器外面再封装一层函数。
return function(target) {
target.isTestable = isTestable;
}
}
@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true
@testable(false)
class MyClass {}
MyClass.isTestable // false
参考链接:https://es6.ruanyifeng.com/#docs/decorator
装饰器模式
不管是在哪种语言中实现的装饰器,其实都源自于装饰器模式。
即,动态的进行增减。
在这里提一句,vue的mixin感觉也是符合装饰器思想的。关于源码的分析,可以参考下面的文章
https://juejin.im/post/5deb0732e51d45582512898a
js中的装饰器和装饰器模式的思想有什么关系?
https://zhuanlan.zhihu.com/p/79030831
常用装饰器
源码分析参考:https://zhuanlan.zhihu.com/p/79030831
ts的语法中并没有vue的写法,所以如果按照ts的语法应该怎么去写vue呢?
换句话说,如何把vue的代码写的更像类的写法呢?
借助装饰器来实现Vue Class Component
是一个封装的装饰器插件,这个插件可以让vue组件看上去更像类。
把vue的写法转换成类的写法,就是核心。
-
@component 通过这个装饰器可以转化vue代码的整体形式。
vue写法:
export default { data () { return { name: 'Simon Zhang' } }, mounted () { this.sayHello() }, computed: { MyName() { return `My name is ${this.name}` } }, methods: { sayHello() { alert(`Hello ${this.name}`) }, } }
ts写法:
@component用法 https://my.oschina.net/lpcysz/blog/2980469 import {Component, Prop, Vue} from 'vue-property-decorator' @Component export default class App extends Vue { name:string = 'Simon Zhang' // computed get MyName():string { return `My name is ${this.name}` } // methods sayHello():void { alert(`Hello ${this.name}`) } mounted() { this.sayHello(); } }
-
@watch
vue写法
export default {
watch: {
'person': {
handler: 'onPersonChanged',
immediate: true,
deep: true
}
},
methods: {
onPersonChanged(val, oldVal) { }
}
}
js写法
import {Vue, Component, Watch} from 'vue-property-decorator';
@Component
export default class YourComponent extends Vue{
@Watch('person', { immediate: true, deep: true })
onPersonChanged(val: Person, oldVal: Person) { }
}
- @prop 在vue中,子组件接受父组件的参数可以使用props。使用封装的装饰器有两种写法:
可以在component中直接定义props
@Component({
props: {
image: {
type: Array
},
}
})
也可以通过 @prop 装饰器。我感觉这个装饰器是一个说明。
vue实现
export default{
props:{
propA:String, // propA:Number
propB:[String,Number],}}
ts实现
import {Component,Vue,Prop} from vue-property-decorator;
@Component
export default class YourComponent extends Vue {
@Prop(String)
propA:string;
@Prop([String,Number])
propB:string|number;
}