• vue 转换成TS的写法


    这里有一篇文章写得很全面,为了防止丢失,所以原文拷贝下来:、

    最近ひたすら既存のVueプロジェクトのTypeScript化をやっているのでメモとしてまとめます。

    (2019/09/09 追記)
    vue-class-componentはvue3のRFCから外されたようで、現在は、Composition APIがRFCとなっています。
    Composition APIでのTypeScript化についてはこちらの記事をどうぞ
    https://qiita.com/ryo2132/items/f055679e9974dbc3f977

    前提

    • .vueファイルで<script lang="ts">を使う
    • vue-property-decoratorを使ったデコレータ方式のTypeScript化を行う

    data

    dataはそのままクラスのプロパティとして宣言します。

    JavaScript

    <script >
    export default {
      name: 'Human',
      data() {
        return {
          name: '山田 太郎',
          age: 19
        };
      }
    };
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Human extends Vue {
      name: string = '山田 太郎';
      age: number = 19;
    }
    </script>
    

    components

    SFCで他Vueコンポーネントを参照する際に使うComponentsは
    @Component()デコレータにcomponentsをkeyに持つオブジェクトを渡し定義します.

    JavaScript

    <script>
    import Header from './Header'
    import Footer from './Footer'
    
    export default {
      name: 'Page',
      components: {
        Header,
        Footer
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    import Header from './Header.vue';
    import Footer from './Footer.vue';
    
    @Component({
      components: {
        Header,
        Footer
      }
    })
    export default class Page extends Vue {
    }
    </script>
    

    directive

    v-hogeのような独自のdirectiveを追加する場合はそのまま@components()にオブジェクトを渡す

    JavaScript

    <script>
    import HogeDirective from './HogeDirective'
    
    export default {
      name: 'Page',
      directives: {
        hoge: HogeDirective
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    import HogeDirective from './HogeDirective'
    
    @Component({
      directives: {
        hoge: HogeDirective
      }
    })
    export default class Page extends Vue {
    }
    </script>
    

    props

    親コンポーネントからデータを受け取るpropsは@Propデコレータを使い定義します。

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

    JavaScript

    <script>
    export default {
      name: 'Post',
      props: {
        contents: { default: '', type: String, require: true },
        postNumber: { default: 0, type: [Number, String], require: true },
        publish: { default: true, type: Boolean, require: true },
        option: { type: Object, require: false } // optionには {new: boolean, important: boolean, sortNumber: number} が設定される想定
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Prop, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Post extends Vue {
      @Prop({ default: '' })
      contents!: string;
    
      @Prop({ default: 0 })
      postNumber!: number | string;
    
      @Prop({ default: false })
      publish!: boolean;
    
      @Prop
      option?: {
        new: boolean,
        important: boolean,
        sortNumber: number
      };
    }
    </script>
    

    computed

    算出プロパティはgetter付きのメソッドで定義します。

    JavaScript

    <script>
    export default {
      name: 'Human',
      data () {
        return {
          firstName: '太郎',
          lastName: '山田'
        }
      },
      computed: {
        fullName () {
          return `${this.firstName} ${this.lastName}`
        }
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Human extends Vue {
      firstName: string = '太郎';
      lastName: string = '山田';
    
      get fullName() {
        return `${this.firstName} ${this.lastName}`;
      }
    
    }
    </script>
    

    emit

    親コンポーネントに値を送信する$emitは@Emitデコレータを使いfunctionとして定義します。
    メソッド名が、$emitに渡すイベント名がメソッド名と同様の場合は、@Emit()の引数(イベント名)は省略できます。
    ※ 以下のcountUpのケース。camelCaseとkebabe-caseは自動で変換されます

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

    JavaScript

    <script>
    export default {
      name: 'Counter',
      data () {
        return {
          count: 0
        }
      },
      methods: {
        countUp (n) {
          this.count += n
          this.$emit('count-up', n)
        },
        resetCount () {
          this.count = 0
          this.$emit('reset')
        }
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Emit, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Counter extends Vue {
      count: number = 0;
    
      @Emit('count-up')
      countUp(n) {
        this.count += n;
        return n;
      }
    
      @Emit('reset')
      resetCount() {
        this.count = 0;
      }
    }
    </script>
    

    model

    input要素のコンポーネント化の際にvalueが競合しないように用いるmodelは
    @Modelデコレータを使ってプロパティを定義します。

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

    JavaScript

    <script>
    export default {
      name: 'MyRadio',
      model: {
        prop: 'checked',
        event: 'change'
      },
      props: {
        checked: { type: Boolean }
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Model, Vue } from 'vue-property-decorator';
    
    @Component
    export default class MyCheckBox extends Vue {
      @Model('change', { type: Boolean }) readonly checked!: boolean;
    }
    </script>
    

    watch

    dataの変更を検知するWatchは@Watchデコレータを使ってメソッドを定義します。
    optionにwatchオプションのimmediateやdeepもオブジェクトとして渡すことで指定できます。

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

    JavaScript

    <script>
    export default {
      name: 'InputText',
      data () {
        return {
          text: '',
          lengthDiff: 0
        }
      },
      watch: {
        text: function (newText, oldText) {
          this.lengthDiff = newText.length - oldText.length
        }
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue, Watch } from 'vue-property-decorator';
    
    @Component
    export default class InputText extends Vue {
      text: string = '';
      lengthDiff: number = 0;
    
      @Watch('text')
      onTextChanged(newText: string, oldText: string) {
        this.lengthDiff = newText.length - oldText.length;
      }
    }
    </script>
    

    provide, inject

    深い階層でも親コンポーネントと子コンポーネントでデータを共有する際に用いるprovideとinjectは@provide@injectデコレータで定義します。

    @Provide(key?: string | symbol) 
    @Inject(options?: { from?: InjectKey, default?: any } | InjectKey)
    

    JavaScript

    Parent.vue

    <script>
    export default {
      name: 'Parent',
      provide: {
        commonValue: 'foo'
      }
    }
    </script>
    

    Child.vue

    <script>
    export default {
      name: 'Child',
      inject: {
        commonValue: { default: 'hoge' }
      }
    }
    </script>
    

    TypeScript

    Parent.vue

    <script lang="ts">
    import { Component, Provide, Vue } from 'vue-property-decorator';
    
    @Component()
    export default class Parent extends Vue {
      @Provide() commonValue = 'foo';
    }
    </script>
    

    Child.vue

    <script lang="ts">
    import { Component, Inject, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Child extends Vue {
      @Inject({ default: 'hoge' })
      readonly commonValue!: string;
    }
    </script>
    

    mixins

    コンポーネント間の共通処理を定義するミックスインはMixins()の継承を使って表現します。
    ミックスイン自身もVueを継承したクラスとして定義します。
    複数のミックスインを使う場合も、Mixins()の引数として与えることが可能です。
    (最大5つ)
    https://github.com/vuejs/vue-class-component/blob/master/src/util.ts#L35

    JavaScript

    mixinLogger.js

    export default {
      created () {
        const now = new Date
        console.log(`created: ${now}`)
      },
      methods: {
        log (param) {
          console.log(`log: ${param}`)
        }
      }
    }
    

    Human.vue

    <script>
    import MixinLogger from './mixinLogger'
    
    export default {
      name: 'Human',
      mixins: [MixinLogger],
      methods: {
        greeting () {
          console.log('おはよう')
          this.log('call greeting')
        }
      }
    }
    </script>
    

    TypeScript

    mixin.ts

    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class mixinLogger extends Vue {
      created() {
        const now = new Date;
        console.log(`created: ${now}`);
      }
    
      log(param) {
        console.log(`log: ${param}`);
      }
    }
    

    Human.vue

    <script lang="ts">
    import MixinLogger from './mixinLogger';
    import { Component, Mixins } from 'vue-property-decorator';
    
    @Component
    export default class Human extends Mixins(MixinLogger) {
      greeting() {
        console.log('おはよう');
        this.log('call greeting');
      }
    }
    </script>
    

    created, mounted, updated, destroyed ...etc

    ライフサイクルフックはそのまま同名のメソッドとして宣言することですることで実装可能です。

    JavaScript

    <script>
    export default {
      name: 'Human',
      created: function () {
        // 何か処理
      },
      mounted: function () {
        // 何か処理
      },
      updated: function () {
        // 何か処理
      },
      destroyed: function () {
        // 何か処理
      }
    }
    </script>
    

    TypeScript

    <script lang="ts">
    import { Component, Vue } from 'vue-property-decorator';
    
    @Component
    export default class Human extends Vue {
      created() {
        // 何か処理
      }
    
      mounted() {
        // 何か処理
      }
    
      updated() {
        // 何か処理
      }
    
      destroyed() {
        // 何か処理
      }
    }
    </script>

    转载自:https://qiita.com/ryo2132/items/4d43209ea89ad1297426#created-mounted-updated-destroyed-etc
  • 相关阅读:
    c# 线程同步各类锁
    C#_从DataTable中检索信息
    永无BUG
    标志枚举
    将多行按分隔符"|"合成一行
    回车换行浅析
    url传输编码
    xshell 禁用铃声 提示音
    php 编译安装 mysql.so
    301 302 304
  • 原文地址:https://www.cnblogs.com/llcdbk/p/12100680.html
Copyright © 2020-2023  润新知