18
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vue-typesでpropsの型を定義する

Last updated at Posted at 2018-09-01

現状

vueにはpropsで型の定義はできますが、細かく設定しようとすると一々オブジェクト形式で書かないといけなくなるし、ObjectやArrayだとvalidatorを自分で定義しないと全然チェックしてくれないので結構辛くなります。
仮に書けてもオブジェクトの中身がどんなものが入っているか分かりにくく、非常に使いづらいです。

export default {
  props: {
    data: {
      type: Number,
      required: true
    },
    arr: {
      type: Array,
      // 全て文字列か調べる
      validator(arr) {
        return arr.every((item) => typeof item === 'string'));
      }
    },
    obj: {
      type: Object,
      validator(obj) {
        return typeof obj.num === 'number' && typeof obj.text === 'string';
      }
    }
  }
};

解決方法

今回はvue-typesというライブラリを使って型を定義したいと思います。これはReactのprop-typesを参考にして作られたものなので、Reactをやっていた方は馴染みやすいと思います。
https://www.npmjs.com/package/vue-types

サンプルコードも作ったのでこちらも参考にしてみてください。
警告が出るとうるさかったので正しいデータを入れて最初は何も出ないようにしています。
validationチェックを確認したい場合はApp.vueでComponentに渡している値を変えてみてください。
https://codesandbox.io/s/6zj47wkmpw

使い方

ざっと書くとこんな感じになります。後は親から渡されるプロパティがあっていなければ警告が出されます。

import VueTypes from 'vue-types';

export default {
  props: {
    // number型と定義
    data: VueTypes.number,
    // bool型で定義。必須にしたい場合は.isRequiredをつける
    flag: VueTypes.bool.isRequired,
    // arrayOfで配列の中身の型を定義できる
    arr: VueTypes.arrayOf(VueTypes.string).isRequired,
    // オブジェクトのkeyに指定はないが、valueの方はstring型にする
    obj: VueTypes.objectOf(VueTypes.string).isRequired,
    // オブジェクト型で、numとtextにそれぞれnumber型、string型と定義する
    obj2: VueTypes.shape({
      num: VueTypes.number.isRequired,
      text: VueTypes.string.isRequired
    }).isRequired,
    // 配列の中身にオブジェクトの型を設定することもできる
    arrObj: VueType.arrayOf(VueType.shape({
      num: VueType.number.isRequired,
      text: VueType.string.isRequired
    })).isRequired
  }
};

個人的には.isRequiredはデフォルトでついて欲しいですが、Reactのprop-typesもこの仕様なので仕方ないですね。

default値の設定

default値を指定した場合は.def(~)を実行すればいいようです。

VueTypes.number.def(10);
VueTypes.object.def(() => ({ num: 10, text: 'text' }));

何も指定しなかった時はグローバルで定義した値をセットするようで、それが嫌な場合は上書きして使うようになります。僕はboolがtrueになっているのが嫌だったのでfalseに書き換えています。
デフォルトが何になるのかはドキュメントのほうを参照してください。

import VueTypes from 'vue-types';

// default値の設定を上書きする
VueTypes.sensibleDefaults.bool = false;

まとめ

vue-typesはまだそんなに人気がない感じですが、ドキュメントもしっかりしていますし、結構いいものだと思っています。少なくとも現状のVueの設定はかなりやりづらいものがあるので、型の設定をちゃんとするなら今回のようなライブラリを使うか、TypeScriptを使うかの検討をしたほうがいいと思いました。

18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?