vue-property-decorator基础教程
为什么要使用vue-property-decorator
如何使用vue-property-decorator
1. 基本写法
2. data中定义数据
3.生命周期钩子函数
4. 方法
5. @Component()
6. @Prop()
7. @PropSync()
8. @Emit()
9. 计算属性
10. @Watch()
为什么要使用vue-property-decorator
vue-property-decorator是在vue-class-component的基础上做了进一步的封装,在TypeScript官方文档 中,官方推荐了vue-class-component,提供了Vue,Component等,而vue-property-decorator是社区出品,深度依赖于vue-class-component,提供了更多操作符:@Component,@Prop,@Watch,@Emit……
如何使用vue-property-decorator
1. 基本写法
template和css的写法不变,只是script内的写法需要注意
<script lang='ts'>
import {Component, Vue} from vue-property-decorator;
@Component
export default class App extends Vue {
};
</script>
lang="ts"
:script声明当前语言是ts@Component
:注明此类为一个vue组件export default class Test extends Vue
: export当前组件类是继承vue的
2. data中定义数据
data中的数据由原来的data()方法改成直接在对象中定义,data内的属性直接作为实例属性书写,默认都是public公有属性
export default class App extends Vue {
private msg1 : string = '123';
private msg2 : number = 1;
}
3.生命周期钩子函数
export default class App extends Vue {
private created(){
this.init();
}
}
4. 方法
export default class App extends Vue {
private init(){
console.log('init');
}
}
5. @Component()
<script lang="ts">
@Component({
components: {
HelloWorld, // 声明子组件的引用
}
})
export default class App extends Vue {}
</script>
6. @Prop()
参数可以传
Constructor 例如String, Number, Boolean
Constructor[], 构造函数的队列, 类型在这队列中即可
PropOptions
type 类型不对会报错 Invalid prop: type check failed for prop “xxx”. Expected Function, got String with value “xxx”.
default 如果父组件没有传的话为该值, 注意只能用这一种形式来表示默认值, 不能@Prop() name = 1来表示默认值 1, 虽然看起来一样, 但是会在 console 里报错, 不允许修改 props 中的值
required 没有会报错 [Vue warn]: Missing required prop: “xxx”
validator 为一个函数, 参数为传入的值, 比如(value) => value > 100
@Prop()
propA: string
@Prop()
propB: number
@Prop({
type: Number,
validator: (value) => {
return value > 100;
},
required: true
}) private propC!: string // !表示有值, 否则 ts 会告警未初始化
@Prop({
default: 'this is title',
required: true
}) propD!: string; // !表示有值, 否则 ts 会告警未初始化
@Prop({
default: true,
required: true
}) propE: boolean | undefined;
7. @PropSync()
与 Prop 的区别是子组件可以对 props 进行更改, 并同步给父组件
子组件
<template>
<div>
<p>{{count}}</p>
<button @click="innerCount += 1">increment</button>
</div>
</template>
<script lang="ts">
@Component
export default class PropSyncComponent extends Vue {
@PropSync('count') private innerCount!: number // 注意@PropSync 里的参数不能与定义的实例属性同名, 因为还是那个原理, props 是只读的.
}
</script>
父组件:注意父组件里绑定 props 时需要加修饰符 .sync
<template>
<PropSyncComponent :count.sync="count"/>
</template>
<script lang="ts">
@Component({
components: PropSyncComponent
})
export default class PropSyncComponent extends Vue {
@PropSync('count') private innerCount!: number // 注意@PropSync 里的参数不能与定义的实例属性同名, 因为还是那个原理, props 是只读的.
}
</script>
8. @Emit()
定义emit事件,参数字符串表示分发的事件名,如果没有,则使用方法名作为分发事件名,会自动转连字符写法:
- @Emit()不传参数,那么它触发的事件名就是它所修饰的函数名.
- @Emit(name: string),里面传递一个字符串,该字符串为要触发的事件名.
js写法
export default {
data() {
return {
count: 0
}
},
methods: {
addToCount(n) {
this.count += n
this.$emit('add-to-count', n)
},
resetCount() {
this.count = 0
this.$emit('reset')
},
returnValue() {
this.$emit('return-value', 10)
},
promise() {
const promise = new Promise(resolve => {
setTimeout(() => {
resolve(20)
}, 0)
})
promise.then(value => {
this.$emit('promise', value)
})
}
}
}
ts写法
查看代码
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
count = 0
@Emit()
addToCount(n: number) {
this.count += n
}
@Emit('reset')
resetCount() {
this.count = 0
}
@Emit()
returnValue() {
return 10
}
@Emit()
promise() {
return new Promise(resolve => {
setTimeout(() => {
resolve(20)
}, 0)
})
}
}
9. 计算属性
对于Vue中的计算属性,我们只需要将该计算属性名定义为一个函数,,在函数前加上get关键字即可,原本Vue中的computed里的每个计算属性都变成了在前缀添加get的函数。
public get computedMsg(){
return '这里是计算属性' + this.message;
}
public set computedMsg(message: string){
}
10. @Watch()
监听属性发生更改时被触发. 可接受配置参数 options
immediate: boolean
是否在侦听开始之后立即调用该函数deep: boolean
是否深度监听.import { Vue, Component, Watch } from vue-property-decorator; export default class App extends Vue { @Watch('child') onChangeChildValue(newValue: string, oldValue: string){ ......todo } @Watch('parent', {immediate: true, deep: false}) private onChangeParentValue(newValue: string, oldValue: string){ ......todo } }