buddywang / blog

0 stars 0 forks source link

用class+ts编写vue组件:vue-property-decorator相关 #21

Open buddywang opened 4 years ago

buddywang commented 4 years ago

用法

@Component:表示一个vue组件

@Component({ components: { OtherComponent } }) export default class "组件名" extends Vue{ value1: string = 'hello' get value2() {...} set value2(val: string) {...} getData() {...} mounted() {...}

}

等同于
```javascript
export default {
    components: {
        OtherComponent
    },
    data(){
        return {
            value1: 'hello'
        }
    },
    computed: {
        value2: {
            get() {...},
            set() {...}
        }
    },
    methods: {
        getData() {...}
    },
    mounted() {...}
}

@Prop(options: (PropOptions | Constructor[] | Constructor) = {})

import { Vue, Component, Prop } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Prop(Number) readonly propA: number | undefined
  @Prop({ default: 'default value' }) readonly propB!: string
  @Prop([String, Boolean]) readonly propC: string | boolean | undefined
}

等同于

export default {
  props: {
    propA: {
      type: Number,
    },
    propB: {
      default: 'default value',
    },
    propC: {
      type: [String, Boolean],
    },
  },
}

@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})

import { Vue, Component, PropSync } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @PropSync('name', { type: String }) syncedName!: string
}

等同于

export default {
  props: {
    name: {
      type: String,
    },
  },
  computed: {
    syncedName: {
      get() {
        return this.name
      },
      set(value) {
        this.$emit('update:name', value)
      },
    },
  },
}

@Watch(path: string, options: WatchOptions = {})

import { Vue, Component, Watch } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Watch('child')
  onChildChanged(val: string, oldVal: string) {}

  @Watch('person', { immediate: true, deep: true })
  onPersonChanged1(val: Person, oldVal: Person) {}

  @Watch('person')
  onPersonChanged2(val: Person, oldVal: Person) {}
}

等同于

export default {
  watch: {
    child: [
      {
        handler: 'onChildChanged',
      },
    ],
    person: [
      {
        handler: 'onPersonChanged1',
        immediate: true, // 默认false
        deep: true, // 默认false
      },
      {
        handler: 'onPersonChanged2',
      },
    ],
  },
  methods: {
    onChildChanged(val, oldVal) {},
    onPersonChanged1(val, oldVal) {},
    onPersonChanged2(val, oldVal) {},
  },
}

@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})

import { Vue, Component, Model } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Model('change', { type: Boolean }) readonly checked!: boolean
}

等同于

export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
}

@Emit(event?: string)

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()
  onInputChange(e) {
    return e.target.value
  }

  @Emit()
  promise() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(20)
      }, 0)
    })
  }
}

等同于

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)
    },
    onInputChange(e) {
      this.$emit('on-input-change', e.target.value, e)
    },
    promise() {
      const promise = new Promise((resolve) => {
        setTimeout(() => {
          resolve(20)
        }, 0)
      })

      promise.then((value) => {
        this.$emit('promise', value)
      })
    },
  },
}

@Provide

@Inject

@ProvideReactive

@InjectReactive

@Ref

等同于