zoukankan      html  css  js  c++  java
  • 装饰器vue-property-decorator

    接触到了新的vue项目,使用vue+ts+vue-property-decotator来进行项目的简化,一时间语法没有看懂,所以花时间学习这个装饰器的包。

    1.装饰器 @Component(options:Component = {})

    默认接受一个对象作为参数,在这个对象中声明components、 filters、 directives等未提供装饰符的选项,也可以声明computed、watch等

    import { Component, Vue } from 'vue-property-decorator'
    import Gap from './Gap.vue'
    
    @Component({
        components: {
            Gap,
        }
    })
    export default class CorrectQuestionResult extends Vue{
        get trueAnswerText () {
            const trueAnswer = this.trueAnswer.ecAnswers![0]
            return this.formatAnswerDesc(trueAnswer.operation!, trueAnswer.source!, trueAnswer.target!)
        }
    }

    在@component中声明了引入的组件,组件的写法也发生了改变,export default class '组件name' extends Vue, 在vue中data、computed的形式也发生改变

    <script lang="ts">
        import {Vue, Component} from 'vue-property-decorator';
    
        @Component({})
        export default class "组件名" extends Vue{
            ValA: string = "hello world";
            ValB: number = 1;
            get val() {
                 return this.ValB + 1;
                }
        }
    </script>    

    等同于

    <script>
        export default {
           data() {
               return {
                  ValA: string = "hello world";
                  ValB: number = 1;
             }
           },
          computed: {
              val() {
                  return this.ValB + 1;
               }
          }
        }
    </script>

    2.@Prop(options: (PropOptions | construct[] | construct))

     @Prop接受一个参数,可以有三种写法

        Constructor,例如String,Number, Boolean等,指定prop的类型

        Constructor[],指定prop的类型

        PropOptions,可以使用以下选项:type,default,required,validator

    import { Vue, Component, Prop } from 'vue-property-decorator'
    
    @Componentexport default class MyComponent extends Vue {
      @Prop(String) public propA: string | undefined
      @Prop([String, Number]) public propB!: string | number
      @Prop({
        type: String,
        default: 'abc'
      })
      public propC!: string
    }

    warning:

        属性的ts类型后面需要加上undefined类型;或者在属性名后面加上!,表示非null 和 非undefined

    的断言,否则编译器会给出错误提示

        指定默认值必须使用上面例子中的写法,如果直接在属性名后面赋值,会重写这个属性,并且会报错。

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

      装饰自定义Model,自定义v-model,接收两个参数:1.event 2. prop; 和vue官方的参数一致,只是装饰器写法稍有不同。

    import { Vue, Component, Model } from 'vue-property-decorator'
    
    @Component
    export default class MyInput extends Vue {
      @Model('change', { type: String, default: '123' }) public value!: string
    }

    需要在父组件中配合

    <input
        type="text"
        v-model="value"  // 真的
        :value="value" // 假的
        @change="$emit('change', $event.target.value)" // 假的
      />

    4.@Watch (path: string, options:watchOptions = {}), 接收两个参数 path: 被监听的属性名, 监听的条件:{immediate: boolean , 监听之后是否立即调用该毁掉函数; deep:boolean,被监听的对象属性改变,是否调用该函数}

    import { Vue, Component, Watch } from 'vue-property-decorator'
    
    @Component
    export default class MyInput extends Vue {
      @Watch('msg')
      public onMsgChanged(newValue: string, oldValue: string) {}
    
      @Watch('arr', { immediate: true, deep: true })
      public onArrChanged1(newValue: number[], oldValue: number[]) {}
    
      @Watch('arr')
      public onArrChanged2(newValue: number[], oldValue: number[]) {}
    }

     5.@Emit装饰器

        1.接收一个可选参数,该参数是$emit的第一个参数(事件名),如果没有提供这个参数,$emit会将回调函数的cameCase转为kebab-case,作为事件名

        2.会将回调函数的返回值作为第二个参数,如果返回值是一个promise对象,$emit会在promise状态改为resolve之后触发。

        3.emit回调函数的参数,将会放在其返回值之后,一起被$emit当作参数使用。

    import { Vue, Component, Emit } from 'vue-property-decorator'
    
    @Component
    export default class MyComponent extends Vue {
      count = 0
      @Emit()
      public addToCount(n: number) {
        this.count += n
      }
      @Emit('reset')
      public resetCount() {
        this.count = 0
      }
      @Emit()
      public returnValue() {
        return 10
      }
      @Emit()
      public onInputChange(e) {
        return e.target.value
      }
      @Emit()
      public 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)
          })
        }
      }
    }

    6.Mixins在vue中有两种配合typescript的混合方法,一种需要定义接口、一种不需要定义vue/type/vue模块

    //定义要混合的类 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 也可以正常运行
          created(){
              console.log(this.value) // => Hello
        }
    }

    第二种方式,需要定义vue/type/vue模块,1.改造混入的ts文件定义 vue/type/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
        }
    }

    两种方法的不同是定义vue/type/vue模块,在混入的时候就要继承该mixins,,如果是定了该模块,直接在@Component中混入即可

  • 相关阅读:
    Keepalived安装配置
    Playbook 角色(Roles) 和 Include 语句
    Ansible Playbook
    ansible的Ad-hoc命令
    Android线程简介
    宝岛探险,DFS&BFS
    再解炸弹人,dfs&bfs
    解救小哈——bfs广搜
    解救小哈——dfs深搜
    数的全排列
  • 原文地址:https://www.cnblogs.com/czy960731/p/11837217.html
Copyright © 2011-2022 走看看