Vue.jsをTypeScriptで書くときには、vue-class-componentやvue-propaty-decoratorを使うような情報ふが多いですが、Vue.extend
を使うとそれらを使わないピュアなVue.jsでもTypeScriptを使って書くことが出来ます。
そのへんの書き方とかを、あまり理解出来てなかったのでMEMOしておきます✍
基本的な書き方
下記にvue-class-component
のOverviewにあったカウンターをちょっと改変してVue.extend
を使って書き直したものを記載しました
vue-class-component
だと素のVue.jsのコンポーネントとかなり書き方が違ってしまうのですが、
<template> <div> <button @click="decrement(1)">-</button> {{ count }} <button @click="increment(1)">+</button> </div> </template> <script lang="ts"> import Vue from 'vue' interface Data { count: number } export default Vue.extend({ props: { initCount: Number }, data() : Data { return { count: this.initCount | 0 } }, methods: { decrement(num: number) { this.count -= num; }, increment(num: number) { this.count += num } } }) </script>
ちょっとDataの型指定が癖がある感じがしますが素のVue.jsのコンポーネントライクで書けるので読みやすいですね👍
Propsを独自で定義したObjectで受け取るケースは下記のような形になるようです👀
※下記は受け取ったコメントのオブジェクトをそのまま表示するようなコンポーネントです
<template> <div class="comment" style="border: solid; margin: 5px;"> <p class="attribute">{{comment.id}}</p> <p class="attribute">{{comment.body}}</p> </div> </template> <script lang="ts"> import Vue, { PropType } from 'vue' import { Comment } from '../types/types' export default Vue.extend({ props: { comment: Object as PropType<Comment> } }) </script>
PropTypeはVue.jsのAPIです。 https://github.com/vuejs/vue/issues/6850
Vue.jsのpropsは内部的にはObjectそのものではなくObjectのコンストラクタが渡されており、 TypeScriptの型情報はObjectのコンストラクタの実行時には存在しないのでエラーになってしまうようです。(あまりわかってない)
そのため今までは関数として定義していたようですが、それがわかりにくいということでPropType
が追加された経緯のようです。
<template> <div class="comment" style="border: solid; margin: 5px;"> <p class="attribute">{{comment.id}}</p> <p class="attribute">{{comment.body}}</p> </div> </template> <script lang="ts"> import Vue, { PropType } from 'vue' import { Comment } from '../types/types' export default Vue.extend({ props: { comment: Object as (() => Comment) } }) </script>