designsupply.llc
  • aboutabout
  • servicesservices
  • worksworks
  • mediamedia
  • contactcontact
  • homeサイトトップ
  • about会社概要
  • services業務内容
  • works実績紹介
  • mediaメディア
  • contactお問い合わせ
ja/

media

メディア

  1. サイトトップ
  2. メディア
  3. プログラミングの記事
  4. Vue.jsの2系でTypeScriptを使う「Options API」と「Class API」

Vue.jsの2系でTypeScriptを使う「Options API」と「Class API」

  • 2021.10.20
  • プログラミング
  • Vue.js
Updated: 2021.10.28
Vue.jsでTypeScriptを使う場合、型指定を行う場合には少し書き方が異なり、2系の場合には「Options API」もしくは「Class API」を使う形になります。現在Vue.jsは3系もリリースされており「Composition API」というのも登場しますが、これについてはまた改めて別記事にまとめていきたいと思います。Vue.jsの最新版は3系になりますが、まだまだ2系も使われていることが多いかと思います、その中でTypeScriptに移行するというケースもあるようですので、ちょっと今更感はありますが今回は備忘録として残しておきたいと思います。   過去記事「webpack&TypeScriptのプロジェクトでVue.jsを使える開発環境を構築してみる」でもVue.jsでTypeScriptを使う環境構築についてまとめていましたが、詳しい書き方などはそこまで触れていなかったので、今回はその点を中心にまとめていきます。   まず、TypeScriptではなく通常のJavaScriptで記述する場合に、コンポーネントの基本の形としては下記のようになります。
<script>
  import { ChildComponent } from '~/components/ChildComponent';
  export default {
    name: 'ExampleComponent',
    components: {
      ChildComponent
    },
    props: {
      isDisplay: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        message: 'hello world!'
      }
    },
    computed: {
      messageConvert() => this.message.toUpperCase();
    },
    created() {
      this.displayMessage();
    },
    methods: {
      displayMessage() {
        if(this.isDisplay) {
          return this.messageConvert();
        } else {
          return false
        }
      }
    }
  }
</script>
  TypeScriptを使う場合にはここに型定義を追加していくのですが、そのままつけることができないので、次のいずれかの方法に変える必要があります。  
Vue.jsのオプションをベース記述できる「Options API」
「Options API」はVue.jsの拡張という位置付けで、元の記述をベースに型定義をそのまま追加できる形になります。メリットとしてはTypeScriptの移行コストや学習コストが低いというものがあります。もともとVue.jsに含まれる型チェックの機能を利用するため、vueをインポートし、Vue.extend()で継承するようにします。これでTypeScriptが有効になります。合わせてscriptタグのlang属性に「ts」と追加しておくのも忘れないようにします。
<script lang="ts">
  import Vue from 'vue'
  import { ChildComponent } from '~/components/ChildComponent';
  export default Vue.extend({
    name: 'ExampleComponent',
    components: {
      ChildComponent
    },
    props: {
      isDisplay: {
        type: Boolean,
        default: true
     }
    },
    data() {
      return {
        message: 'hello world!' as string
      }
    },
    computed: {
      messageConvert(): string {
        return this.message.toUpperCase();
      }
    },
    created() {
      this.displayMessage(this.messageConvert);
    },
    methods: {
      displayMessage(message: string): string | boolean {
        if(this.isDisplay) {
          return message;
        } else {
          return false
        }
      }
    }
  })
</script>
  このように、Options APIではVue.jsのオプションについてこれまでと同じように定義し、それぞれ変数や関数の返り値の型定義を行なっていきます。TypeScriptに慣れていない・詳しくない場合や、これまで通りのVue.jsの記法が良いという場合にはこの形の方が良さそうですね。ただ、型定義のエラーが結構出てしまう印象があり、どちらかというとこのあと紹介するクラスベースのClass APIの方が情報も充実しているのかなと思いますので、本格的に導入する場合には検討の余地がありそうという感じでしょうか。また次のクラスベースの書き方より少しコードが長くなったり見通しもあまり良く無いというのが気になります。  
クラスベースで記述できる「Class API」
「Class API」ではこれまでのVue.jsのオプションの書き方とは異なり、クラスを定義してエクスポートするような形になります。また、Vue.jsで使われているオプションに対応させるために@から始まるデコレーターというものを使います。このため、Class APIの場合には下記のモジュールを追加でインストールしておきます。
$ npm install --save vue-property-decorator vue-class-component
  モジュールがインストールできればクラスベースでVue.jsのtypescriptへの移行ができるようになります。下記のようにモジュールやコンポーネントをインポートして、クラスを定義していきます。その時にコンポーネントなどについてはデコレーターを使って記述していきます。コンポーネントは「@Component()」に続いて読み込むものを指定していきます。   Propsも同じで「@Prop()」のデコレーターを使って値を受け取ります。引数には受け取る値の型や初期値などの指定が入ります。その後続けて、受け取る値のキー名を型定義して指定します。その後、続けてVue.jsのオプションを記述していきます。
<script lang="ts">
  import { Component, Prop, Emit, Watch, Vue } from 'vue-property-decorator';
  import ChildComponent from '~/components/ChildComponent.vue';
  @Component({
    components: {
      ChildComponent
    }
  })
  export default class ExampleComponent extends Vue {
    @Prop({ type: Boolean, default: true })
    isDisplay?: boolean;
    message: string = 'hello world!';
    get messageConvert(): string {
      return this.message.toUpperCase();
    }
    created() {
      this.displayMessage(this.messageConvert);
    }
    displayMessage(message: string): string | boolean {
      if(this.isDisplay) {
        return message;
      } else {
        return false
      }
    }
  }
</script>
  各オプションですが、まずdataオプションについては、クラス内の変数としてキーと合わせて定義します。そして、computedに関してはgetアクセサに続いて関数を定義します。setterとして使う場合にはsetアクセサを使って同じように記述します。created()やmounted()などのライフサイクルフックはそのままのオプションの書き方で定義していき、methodsについてはクラス内の関数として個別に定義していきます。   これまでのオプションの書き方とは異なる部分がたくさんあり、慣れないうちはややこしく感じるのですが、見てわかる通り全体的にコードがすっきりとしているのがわかります。個人的には型定義関連のエラーで躓くことがOptions APIと比べると少ない印象があり、情報もこちらの方が多いため良く使われているのかなと思います。ただ、Vue3系ではこの方法が採用されていないようですが、、   上記以外にもWatchやmixin、middleware、またstore内の処理なども少し書き方が異なる部分があるのですが、それらについてはまた改めて別記事でまとめていきたいと思います。  
クラスベースの記述でコンポーネントが正しく読み込まれない
Class APIでの書き方で1点注意しておきたいのが、コンポーネントとして複数を読み込む際に、うまく表示されないという現象が起こることがありました。下記のように、親コンポーネント側で、子コンポーネントを個別に読み込んでいくのですが、なぜか全て同一のコンポーネントとして表示されてしまっている状態になっていました。
import ChildComponent1 from '~/components/common/ChildComponent1.vue'
import ChildComponent2 from '~/components/common/ChildComponent2.vue'
@Component({
  components: {
    ChildComponent1,
    ChildComponent2
  }
})
export default class ParentComponent extends Vue {
  ....
}
  子コンポーネント側(一部抜粋)ではこのようにコンポーネントを定義しており、その中では特にコンポーネントを呼び出すこともないので、@Component()のデコレーターも使わず記述している形でした。
// コンポーネント1
export default class ChildComponent1 extends Vue {
  ....
}

// コンポーネント2
export default class ChildComponent2 extends Vue {
  ....
}
  どうやらそれが原因だったようで、コンポーネント側では、そのコンポーネント内で読み込むものがない場合にも、@Component()のデコレーターでは空として記述しておく必要があるようです。こうすることで正しくコンポーネントが呼び出されるようになりました。
// コンポーネント1
@Component({})
export default class ChildComponent1 extends Vue {
  ....
}

// コンポーネント2
@Component({})
export default class ChildComponent2 extends Vue {
  ....
}
 
  今回はVue.jsでTypeScriptを使う場合の記述方法である「Options API」と「Class API」について基本的な部分をまとめてみました。今回まとめている以外にも知っておくべき知識もあるのですが、まずは基本的な部分は押さえておきたいですね。色々と覚えることが大変なので、やはり良く言われている通りVue.jsとTypeScriptはあまり相性が良くないのかなという印象を感じました、、どちらでもTypeScriptに対応はできるので、状況や優先事項に合わせて使い分けられるといいですね。   (参考にさせて頂いたサイト) Vue.js to TypeScriptの書き方一覧

この記事を書いた人オガワ シンヤ

合同会社デザインサプライ代表兼CEO / ディレクター・ウェブデザイナー・フロントエンドエンジニアをやっています。「ウェブとデザインでヒト・モノ・サービスを繋げ新しい価値を生み出す」をコンセプトに日々奮闘中!制作中はダイエットコーラとチョコレートが欠かせないアラフォーWebクリエイター。

Sponsored Link

  • Showcase
  • Startify UI
  • Functional Gradation Generator
  • Coloooors

categories

  • WordPress(61)
  • JavaScript(49)
  • Vue.js(48)
  • CSS(46)
  • jQuery(34)
  • Nuxt.js(22)
  • Sass(21)
  • Gulp(17)
  • webpack(16)
  • PHP(14)
  • HTML(14)
  • GSAP(11)
  • React(10)
  • Vite(9)
  • Pug(9)
  • Laravel(8)
  • Cordova(8)
  • Linux(7)
  • Next.js(6)
  • Apache(5)
  • Shopify(4)
  • REST API(4)
  • Node.js(4)
  • Smarty(3)
  • Git(3)
  • JSON(3)
  • その他プログラミング(3)
  • Google Apps API(3)
  • Bootstrap(3)
  • 環境構築・システム(3)
  • TypeScript(2)
  • EJS(2)
  • RMS(2)
  • Docker(2)
  • Instagram API(2)
  • Excel VBA(2)
  • SVG(1)
  • Dart(1)
  • ECカートASP(1)
  • Markdown(1)
  • AMP(1)
  • Nginx(1)
  • XML(1)
  • shellscript(1)
  • Ruby(1)
  • MySQL(1)
  • 次の記事
  • 一覧に戻る
  • 前の記事

まだ依頼内容が決まっていなくても、ご相談ください。

課題の整理や小さな検証、UI/UX・フロントエンドの部分的な支援から始められます。

お問い合わせやご相談はこちらから

Webサイト・プロダクトの企画設計/UI・UXデザイン/フロントエンド開発合同会社デザインサプライ(DesignSupply. LLC)

Office:大阪府大阪市天王寺区清水谷町3-22
Email:info@designsupply-web.com
home
  • サイトトップ
about
  • 3つのポリシー
  • 経営理念
  • 代表・クリエイター紹介
  • 会社概要
services
  • ビジネス・プロダクト支援
  • UI/UX・フロントエンド開発支援
  • プロジェクトの進め方・支援体制
  • エデュケーション事業
works
  • 開発プロジェクト
  • クリエイティブ支援
  • 自社プロダクト
media
  • デザイン
  • プログラミング
  • マーケティング
  • Web開発
  • 写真・動画制作
contact
  • お問い合わせ
news
  • インフォメーション
privacy
  • プライバシーポリシー

WE THINK WITH YOU, DESIGN FOR PEOPLE, AND BUILD WHAT WORKS.

WE THINK WITH YOU, DESIGN FOR PEOPLE, AND BUILD WHAT WORKS.

© 2013 - 2026 DesignSupply.LLC
サイトトップへ
contact