Vue.js propsとdataの違い
Rev.4を表示中。最新版はこちら。
1. 概要
Vue.jsでpropsとdataの違いは何?とたまに聞かれるので、そのメモとサンプル。インスタンス内からはどちらもthis.xxxでアクセスできるため、余計に区別がつかなくなるのだと思う。
2. プロパティはどのように使うか
まず前提として、プロパティ(props)はVueインスタンスではなく、コンポーネント(Vue.component)内で使うもの。
その上で、プロパティは親からコンポーネントにパラメータを渡すのに使用する。具体的にはプロパティを使うのは以下のケースがある。
(1) タグの属性でパラメータを渡したい場合
コンポーネントタグの属性でパラメータを渡したい場合はプロパティ(props)を使う必要がある。dataでは渡せない。
サンプル1: https://www.bit-hive.com/~tomita/data_vs_props2/example.html
(サンプルは単体のhtmlにまとまっているので、ソースを表示すれば内容は簡単に確認できます)
MyComponentコンポーネントには以下のようにtitle_in_propsプロパティとtitle_in_dataデータが定義されている。
props: ['title_in_props'], data: function () { return {title_in_data: '--'}; }
このコンポーネントに以下のように属性でtitle_in_propsとtitle_in_dataを指定してみる。
<my-component title_in_props="foo" title_in_data="bar"></my-component>
表示結果は以下となり、プロパティのtitle_in_propsのみ設定できていることが確認できる。
Title In Props: foo, Title In Data: --
(2) 親から子コンポーネントへパラメータを渡したい場合
v-bind:<プロパティ名>でコンポーネントのプロパティと親のデータをバインディングすれば、親のデータを変更した際、子のプロパティも更新される。
サンプル2: https://www.bit-hive.com/~tomita/data_vs_props2/example2.html
このサンプルでは以下のtitleプロパティを持つNewsComponentとtitleの大元のデータを持つVueインスタンスが存在する。
Vue.component('NewsComponent', { template: '<p>Title: {{ title }}</p>', props: ['title'] }); var vm = new Vue({ el: '#app', data: { news: {title: 'Hello'} } });
表示しているNewsComponentには以下のようにv-bindでVueインスタンスのnews.titleのデータをバインディングしている。
<news-component v-bind:title="news.title" ref="component1"></news-component>
「Add ! to parent data.」ボタンを押すとVueインスタンスのnews.titleの末尾にエクスクラメーションマーク(!)を追加する。news.titleを更新すると、バインディングしたNewsComponentのtitleプロパティも更新され、表示も更新される。
このように親のデータが変更されたらコンポーネント内のデータを更新したい場合にプロパティを使用する。
「Add ? to title property directly.」ボタンの方はここでは説明しない。「3. プロパティの単方向データフロー」で説明する。
上記以外ケースではdataを使えばよい。
3. プロパティの単方向データフロー
上記(2)に関連するが、親のプロパティを更新すると子のプロパティも更新されるが、逆はない。必ず親→子への単方向の伝搬となる。
このため、子のプロパティを直接変更することはしてはいけない。変更するとコンソールに警告が出力される。また、子のプロパティを変更しても、親のデータ更新時に再伝搬され上書きされてしまうので意味がない。
これはサンプル2の「Add ? to title property directly.」ボタンを押した後、「Add ! to parent data.」ボタンを押すことで確認できる。(「Add ? to title property directly.」はコンポーネントのプロパティを直接変更する)
値を変更する必要がある場合は、プロパティの値を基にdataやcomputed propertyを使って実装する。
JavaScriptコンソールに表示されるwarning
4. 参考URL
上記のことは、以下のドキュメントを読めば理解できるはずだ。
https://jp.vuejs.org/v2/guide/components.html のプロパティに関する部分。
https://jp.vuejs.org/v2/guide/components-props.html の特に単方向データフローの部分。