vue-property-decorator使用指南

在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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容