TypeScriptでクラススタイルコンポーネントを実装する方法

Vue.jsのコンポーネントをTypeScriptで実装する方法について確認します。vue-class-componentvue-property-decorator を利用したクラススタイルコンポーネントの実装方法を取り上げます。

動作確認用の環境構築

Vue CLI でTypeScriptコンポーネントのプロジェクトを構築してみます。

$ vue create ts-test

class-style componentの形式でTypeScriptを利用できるように指定します。

? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Pick a linter / formatter config: TSLint
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No

プロジェクトの構築が完了したので、フォルダを確認してみます。

$ cd ts-test/
$ tree -L 1
.
├── README.md
├── babel.config.js
├── node_modules
├── package.json
├── postcss.config.js
├── public
├── src
├── tsconfig.json
├── tslint.json
└── yarn.lock

3 directories, 7 files

package.jsonの記述を確認します。

$ cat package.json
{
  "name": "ts-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^2.6.5",
    "vue": "^2.6.10",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.8.0",
    "@vue/cli-plugin-typescript": "^3.8.0",
    "@vue/cli-service": "^3.8.0",
    "typescript": "^3.4.3",
    "vue-template-compiler": "^2.6.10"
  }
}

vue-class-componentvue-property-decorator が含まれています。

クラススタイルコンポーネント

サンプルコンポーネントを確認

プロジェクト構築時に生成された、class-styleのコンポーネント( components/HelloWorld.vue )について確認します。

$ cat src/components/HelloWorld.vue | awk '/<script/,/<\/script/'
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}
</script>

script 内の実装を抽出しています。以下のことが読み取れます。

  • lang="ts" となっています。
  • vue-property-decorator を読み込んでいます。
  • TypeScriptのDecoratorを活用して、クラススタイルのコンポーネントを生成しています。

なお、Decoratorを利用できるように、tsconfig.json にて experimentalDecorators を有効にしています。

$ grep experimentalDecorators tsconfig.json 
    "experimentalDecorators": true,

vue-property-decoratorについて

vue-property-decorator は、vue-class-component をさらに使いやすくするためのものです。

例えば、vue-class-component だけだと props は、@Componentデコレータ 内部に記述します。
vue-property-decorator@Propデコレータ を利用するとクラスメンバとして記述できます。

参考

https://egghead.io/lessons/vue-js-define-props-on-a-vue-class-with-vue-property-decorator

書き方を整理

項目 クラススタイルコンポーネント
methods class methods として記述
( vue-class-component )
computed properties class property accessors(getter) として記述
( vue-class-component )
data class properties として記述
( vue-class-component )
lifecycle hooks
( created mounted など)
同じ名前で class methods として記述
( vue-class-component )
mixins mixins helper を利用して記述
( vue-class-component )
props @Prop を利用して記述
( vue-property-decorator )
watch @Watch を利用して記述
( vue-property-decorator )
emit @Emit を利用して記述
( vue-property-decorator )
その他のプロパティ
( filters components など )
@Component の引数に記述
( vue-class-component )

参考