加载中...
  • vue-property-decorator

    在Vue中使用TypeScript时,非常好用的一个库,使用装饰器来简化书写。

    1、安装npm install –save vue-property-decorator

    这个组件完全依赖于vue-class-component.它具备以下几个属性:

    @Component (from vue-class-component)

    @Prop

    @Model

    @Watch

    @Emit

    @Inject

    @Provide

    Mixins (the helper function named mixins defined at vue-class-component)

    2、@Component

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import {componentA,componentB} from '@/components';

    export default{
    components:{
    componentA,
    componentB,
    },
    directives: {
    focus: {
    // 指令的定义
    inserted: function (el) {
    el.focus()
    }
    }
    }
    }

    ts写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    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
    //如果是对象或数组的话。默认值从一个工厂函数中返回
    // defatult: () => {
    // return ['a','b']
    // }
    required: true,
    validator: (value) => {
    return [
    'InProcess',
    'Settled'
    ].indexOf(value) !== -1
    }
    })
    propC:string;


    }

    4、@Model (组件之间,checkbox)

    父组件中使用 v-model=”checked” 子组件

    1
    <input  type="checkbox" :checked="checked" @change="change">

    js写法 ==(2.2.0+ 新增)==

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    export default {
    model:{
    prop:'checked',
    event:'change'
    },
    props:{
    checked:{
    type:Boolean
    }
    },
    methods:{
    change(e){
    this.$emit('change', e.target.checked)
    }
    }
    }

    ts写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    export default {
    watch: {
    'person': {
    handler: 'onPersonChanged',
    immediate: true,
    deep: true
    }
    },
    methods: {
    onPersonChanged(val, oldVal) { }
    }
    }

    ts写法

    1
    2
    3
    4
    5
    6
    7
    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 定义的函数发出它们的返回值,后跟它们的原始参数。 如果返回值是promise,则在发出之前将其解析。

    如果事件的名称未通过事件参数提供,则使用函数名称。 在这种情况下,camelCase名称将转换为kebab-case。
    js写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    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写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    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 注入

    注:父组件不便于向子组件传递数据,就把数据通过Provide传递下去,然后子组件通过Inject来获取

    js写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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进行开发时我们经常要用到混合,结合TypeScript之后我们有两种mixins的方法.

    一种是vue-class-component提供的

    1
    2
    3
    4
    5
    6
    7
    8
    //定义要混合的类 mixins.ts
    import Vue from 'vue';
    import Component from 'vue-class-component';

    @Component // 一定要用Component修饰
    export default class myMixins extends Vue {
    value: string = "Hello"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 引入
    import Component {mixins} from 'vue-class-component';
    import myMixins from 'mixins.ts';

    @Component
    export class myComponent extends mixins(myMixins) {
    // 直接extends myMinxins 也可以正常运行
    created(){
    console.log(this.value) // => Hello
    }
    }

    第二种方式是在@Component中混入.

    我们改造一下mixins.ts,定义vue/type/vue模块,实现Vue接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 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'
    }

    混入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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
    }
    }

    总结: 两种方式不同的是在定义mixins时如果没有定义vue/type/vue模块, 那么在混入的时候就要继承该mixins; 如果定义vue/type/vue模块,在混入时可以在@Component中mixins直接混入.

    转载自:https://github.com/kaorun343/vue-property-decorator

    上一篇:
    vue-property-decorator
    下一篇:
    好的句子收集一
    本文目录
    本文目录