Vue.jsのコンポーネントは、Vueインスタンスを生成してアプリケーションを作成する場合と同様に、コンポーネント用のデータ(dataプロパティオプション)を持ちます。
コンポーネント内で利用するデータが固定であれば、問題ありませんが利用するデータが変わる場合には、データが違うだけで似たようなコンポーネントをいくつも作る必要があります。
そこでVue.jsには、コンポーネントを利用する側のアプリケーション、または親コンポーネントからデータ(パラメーター)を渡して子コンポーネント側で受け取る仕組みが用意されています。
ここでは、コンポーネントが親のVueインスタンスからデータを受け取るpropsプロパティオプションについて紹介します。
目次
propsプロパティオプション
コンポーネントにpropsプロパティオプションを定義することで、コンポーネントを利用する側の親となるアプリケーションや、親コンポーネントから子コンポーネントにパラメーターを渡すことができるようになります。
propsオプションでパラメーターを受け取ることにより、子コンポーネント側は親から受け取ったパラメーターの値を利用して、コンポーネントの状態を切り分けたり、動作を切り分けたりすることができるようになります。
propsオプションの書式
propsオプションには、定義するプロパティの名前を定義します。
1 2 3 4 |
props: { プロパティ名: { } } |
propsには複数のプロパティが定義できます。複数のプロパティを定義する場合はカンマで区切ります。
1 2 3 4 5 6 7 8 |
props: { プロパティ名1: { }, プロパティ名2: { }, プロパティ名3: { } } |
propsオプションに定義したプロパティには
- type(データ型)
- default(既定値)
- required(プロパティが必須かどうか)
- validator(値の検証関数)
の4つのプロパティオプションが定義できます。
プロパティのオプションを定義することで、propsのプロパティがどのようなプロパティかの検証ルールを設定することができます。
1 2 3 4 5 6 7 8 |
props: { プロパティ名: { type: 値, default: 値または関数, required: 値, validator: 関数 } } |
type
typeにはpropsのプロパティのデータ型を指定します。
typeには
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
が指定できる他、ユーザー定義の任意の型が指定できます。
例えば、propsに定義するプロパティがString型の場合は以下のようになります。
1 2 3 4 5 |
props: { propName: { type: String } } |
プロパティに指定するオプションがtype(データ型)のみの場合は、以下のように記述することもできます。
1 2 3 |
props: { propName: String } |
typeにはデータ型を複数指定することもできます。
プロパティが複数のデータ型を取る場合には、型名を配列として指定します。
例えば、typeにString型とNumber型のいずれかを取るプロパティの場合は以下のようになります。
1 2 3 4 5 |
props: { propName: { type: [String, Number] } } |
default
defaultにはpropsのプロパティにデータ(パラメーター)が指定されなかった場合のデフォルト値(既定値)を指定します。
例えば、String型のpropNameプロパティを定義しており、デフォルト値を空文字列にする場合は以下のようになります。
1 2 3 4 5 6 |
props: { propName: { type: String, default: '' } } |
propsに定義するプロパティのデータ型がObjectやArrayの場合には、ObjectやArrayを返す関数(function())を指定します。
1 2 3 4 5 6 7 8 9 10 11 |
props: { propName: { type: Object, default: function() { return { objectId: 100, objectName: 'abc', } } } } |
required
requiredにはpropsのプロパティの指定が必須(親からpropsに必ずデータが指定される)かどうかを指定します。
指定する値はBoolean型のtrueまたはfalseの真偽値を指定します。
1 2 3 4 5 6 |
props: { propName: { type: String, required: true } } |
requiredにtrueが指定されている場合は、必ず親のアプリケーションまたはコンポーネントからpropsの値を指定する必要があります。
validator
validatorにはpropsのプロパティの値が任意の条件を満たすかどうかを返す関数を指定します。
関数の戻り値にはBoolean型のtrueまたはfalseの真偽値を指定します。
例えば、String型のpropNameプロパティを定義しており、プロパティの値が1文字以上指定されているかどうかを検証する場合は以下のようになります。
1 2 3 4 5 6 7 8 |
props: { propName: { type: String, validator: function(value) { return value.length > 0; } } } |
コンポーネントの定義例
ここではコンポーネントの定義例と、コンポーネントを利用する側のアプリケーションの定義例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const myComponent = { props: { propName: { type: String, default: '', required: true, validator: function(value) { return value.length <= 5; } } }, template: '#component-template' } Vue.createApp({ components: { 'my-component': myComponent } }).mount('#app') |
1 2 3 |
<script type="text/x-template" id="component-template"> <div>{{propName}}</div> </script> |
上記の例では、myComponentというコンポーネントを定義しています。
コンポーネントには、propNameというpropsを定義しています。
propNameは、String型、デフォルト値が空文字列、指定が必須、値が5文字以下であるかを検証の4つのプロパティを指定しています。
propsへのパラメーターの渡し方
子コンポーネントでpropsを定義してパラメーターを受け取る準備ができたら、親側のアプリケーションまたはコンポーネントからpropsにデータを渡します。
コンポーネントのpropsにデータを渡す時は、親側のHTMLテンプレートからv-bindディレクティブを使用してデータを指定します。
上記で定義したコンポーネント「myComponent」のprops「propName」にデータを指定する場合は、以下のようになります。
1 2 3 |
<div id="app"> <my-component v-bind:prop-name="'abc'"></my-component> </div> |
コンポーネントを利用するアプリケーション(または親コンポーネント)のVueインスタンスにマウントする要素(ここではid属性がappのdiv要素)の内部にカスタム要素でコンポーネントを指定し、v-bindディレクティブにpropsの名前を指定して値を設定します。
propsの名前は定義側がキャメルケース(camelCase)で指定されている場合でも、HTMLテンプレート側ではケバブケース(kebab-case)で指定します。
「myComponent」のpropsに定義した「propName」の場合は、v-bindディレクティブで指定する時には「prop-name」となりますのでv-bindディレクティブの記述は「v-bind:prop-name=”‘abc'”」になります。
propsに指定するデータは上記のように直接固定値を指定することもできますが、アプリケーションでは通常dataオプションやcomputedオプションに定義したプロパティを指定することになります。
propsで受け取ったデータの利用
propsのプロパティで受け取ったデータはコンポーネント内に定義したcomputedオプションやmethodsオプションから「this.propsの名前」の形式でアクセスできます。
例えば、propNameをcomputedオプション内で利用する場合は以下のようになります。
1 2 3 4 5 |
computed: { displayText: function() { return 'propsで指定された値は「' + this.propName + '」です。'; } } |
propsで受け取ったデータはコンポーネント内で値を代入しても変更することはできません。propsのデータは読み取り専用になりますので、以下のようなコードを書いてもpropsのデータは変更されません。(コンソールに警告が表示されます。)
1 2 3 4 5 6 |
computed: { displayText: function() { this.propName = "propsのデータはコンポーネント側では変更できません。"; return 'propsで指定された値は「' + this.propName + '」です。'; } } |
まとめ
コンポーネントのpropsプロパティオプションを使用することで、親から子(コンポーネント)へデータを渡すことができます。
propsに定義するプロパティには、データ型、デフォルトの値、必須有無、検証関数が指定できます。
propsで受け取ったデータはコンポーネント内でthis修飾子をつけて参照することができます。
propsで受け取ったデータはコンポーネント内で参照することができますが、変更することはできません。
最後にjsFiddleに貼り付けてコンポーネントの動作を確認できるコードのサンプルを掲載しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<script src="https://unpkg.com/vue@next"></script> <div id="app"> <input v-model="propsData"> <my-component v-bind:prop-name="propsData"></my-component> </div> <script type="text/x-template" id="component-template"> <div>{{displayText}}</div> </script> <script> const myComponent = { props: { propName: { type: String, default: '', required: true, validator: function(value) { return value.length <= 5; } } }, template: '#component-template', computed: { displayText: function() { return '入力された値は「' + this.propName + '」です。'; } } } Vue.createApp({ components: { 'my-component': myComponent }, data: function() { return { propsData: '' } } }).mount('#app') </script> |
上記のコードをコピーしてjsFiddleのHTMLパネルに貼り付けて「Run」をクリックすることで実行結果が確認できます。
jsFiddleの使い方等については、以下の記事をご覧ください。