在Vue中使用TypeScript時(shí),非常好用的一個(gè)庫(kù),使用裝飾器來(lái)簡(jiǎn)化書(shū)寫(xiě)。
1、安裝npm install --save vue-property-decorator
這個(gè)組件完全依賴(lài)于vue-class-component.它具備以下幾個(gè)屬性:
@Component (from vue-class-component)
@Prop
@Model
@Watch
@Emit
@Inject
@Provide
Mixins (the helper function named mixins defined at vue-class-component)
2、@Component
import {componentA,componentB} from '@/components';
export default{
components:{
componentA,
componentB,
},
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
}
ts寫(xiě)法
import {Component,Vue} from 'vue-property-decorator';
import {componentA,componentB} from '@/components';
@Component({
components:{
componentA,
componentB,
},
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
})
export default class YourCompoent extends Vue{
}
3、@Prop 父子組件之間值的傳遞
js寫(xiě)法
export default{
props:{
propA:String, // propA:Number
propB:[String,Number],
propC:{
type:Array,
default:()=>{
return ['a','b']
},
required: true,
validator:(value) => {
return [
'a',
'b'
].indexOf(value) !== -1
}
}
}
}
ts寫(xiě)法
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;
@Prop({
type: String, // type: [String , Number]
default: 'default value', // 一般為String或Number
//如果是對(duì)象或數(shù)組的話(huà)。默認(rèn)值從一個(gè)工廠函數(shù)中返回
// defatult: () => {
// return ['a','b']
// }
required: true,
validator: (value) => {
return [
'InProcess',
'Settled'
].indexOf(value) !== -1
}
})
propC:string;
}
4、@Model (組件之間,checkbox)
父組件中使用 v-model="checked" 子組件
<input type="checkbox" :checked="checked" @change="change">
js寫(xiě)法 ==(2.2.0+ 新增)==
export default {
model:{
prop:'checked',
event:'change'
},
props:{
checked:{
type:Boolean
}
},
methods:{
change(e){
this.$emit('change', e.target.checked)
}
}
}
ts寫(xiě)法
import {Vue,Component,Model,Emit} from 'vue-property-decorator';
@Component
export default class YourComponent extends Vue{
@Model('change',{
type:Boolean
})
checked!:boolean;
@Emit('change')
change(e:MouseEvent){}
}
5、@Watch
js寫(xiě)法
export default {
watch: {
'person': {
handler: 'onPersonChanged',
immediate: true,
deep: true
}
},
methods: {
onPersonChanged(val, oldVal) { }
}
}
ts寫(xiě)法
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) { }
}
6、@Emit
由@Emit $emit 定義的函數(shù)發(fā)出它們的返回值,后跟它們的原始參數(shù)。 如果返回值是promise,則在發(fā)出之前將其解析。
如果事件的名稱(chēng)未通過(guò)事件參數(shù)提供,則使用函數(shù)名稱(chēng)。 在這種情況下,camelCase名稱(chēng)將轉(zhuǎn)換為kebab-case。
js寫(xiě)法
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寫(xiě)法
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)
})
}
}
7、@Provide 提供 / @Inject 注入
注:父組件不便于向子組件傳遞數(shù)據(jù),就把數(shù)據(jù)通過(guò)Provide傳遞下去,然后子組件通過(guò)Inject來(lái)獲取
js寫(xiě)法
const symbol = Symbol('baz')
export const MyComponent = Vue.extend({
inject: {
foo: 'foo',
bar: 'bar',
'optional': { from: 'optional', default: 'default' },
[symbol]: symbol
},
data () {
return {
foo: 'foo',
baz: 'bar'
}
},
provide () {
return {
foo: this.foo,
bar: this.baz
}
}
})
ts寫(xiě)法
import {Vue,Component,Inject,Provide} from 'vue-property-decorator';
const symbol = Symbol('baz')
@Component
export defalut class MyComponent extends Vue{
@Inject()
foo!: string;
@Inject('bar')
bar!: string;
@Inject({
from:'optional',
default:'default'
})
optional!: string;
@Inject(symbol)
baz!: string;
@Provide()
foo = 'foo'
@Provide('bar')
baz = 'bar'
}
8、Mixins
在使用Vue進(jìn)行開(kāi)發(fā)時(shí)我們經(jīng)常要用到混合,結(jié)合TypeScript之后我們有兩種mixins的方法.
一種是vue-class-component提供的
//定義要混合的類(lèi) 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 也可以正常運(yùn)行
created(){
console.log(this.value) // => Hello
}
}
第二種方式是在@Component中混入.
我們改造一下mixins.ts,定義vue/type/vue模塊,實(shí)現(xiàn)Vue接口
// mixins.ts
import { Vue, Component } from 'vue-property-decorator';
declare module 'vue/types/vue' {
interface Vue {
value: string;
}
}
@Component
export default class myMixins extends Vue {
value: string = 'Hello'
}
混入
import { Vue, Component, Prop } from 'vue-property-decorator';
import myMixins from '@static/js/mixins';
@Component({
mixins: [myMixins]
})
export default class myComponent extends Vue{
created(){
console.log(this.value) // => Hello
}
}
總結(jié): 兩種方式不同的是在定義mixins時(shí)如果沒(méi)有定義vue/type/vue模塊, 那么在混入的時(shí)候就要繼承該mixins; 如果定義vue/type/vue模塊,在混入時(shí)可以在@Component中mixins直接混入.
轉(zhuǎn)載自:https://github.com/kaorun343/vue-property-decorator