propsや$emitを使わずに親子コンポーネント間の通信をする $parent、$refs、$root [Vue.js]

Vue.js The Progressive JavaScript Framework

Vue.jsの親子コンポーネント間の通信は、原則としてpropsと$emitを使用します。
子コンポーネントはpropsで親コンポーネントからデータを受け取り、$emitでイベントを発行することで親コンポーネントに通知を行います。
$emitでは引数にデータを指定することで親コンポーネントにデータを渡すこともできます。

Vue.jsでは上記の「Props down, Event up」が基本になりますが、別の方法で親子コンポーネント間でデータを参照する方法も用意されていませす。

そこで今回は、親コンポーネントを参照する$parent、子コンポーネントなどのHTML要素を参照する$refs、コンポーネントツリーのルートを参照する$rootの3つのインスタンスプロパティを紹介します。

$parentプロパティ

$parentプロパティは、現在のコンポーネントの親にあたるコンポーネントのインスタンスを返します。

$parentプロパティの書式

$parentプロパティは、子コンポーネント側で以下のように使用します。

親要素のプロパティには、dataオプションに定義したプロパティや、computedオプションに定義したプロパティを指定できます。

$parentプロパティの使用例

以下に$parentプロパティを使用して親コンポーネントのデータを参照する例を示します。

HTML

JavaScript

ここでは、親のアプリケーションに定義したdataオプションとcomputedオプションのプロパティを、子コンポーネントから参照してテキストボックスに表示しています。

上記の例のコードを実行すると以下の画面が表示されます。

Vue.jsの$parentプロパティの使用例のサンプルコードの実行結果

$refsプロパティ

$refsプロパティは、コンポーネント(カスタム要素)のインスタンスを返します。

$refsプロパティの書式

$parentプロパティは、親コンポーネント側で以下のように使用します。

$refsプロパティを使うためにはHTMLテンプレートに配置する要素にref属性を指定します。ref属性の引数には、$refsプロパティを使用して参照する名前を指定します。

$refsプロパティの使用例

以下に$refsプロパティを使用して親コンポーネントのデータを参照する例を示します。

HTML

JavaScript

ここでは、子コンポーネントに定義したdataオプションのmessageOfChildプロパティの値を親のアプリケーションから参照してます。
HTMLテンプレートで子コンポーネントのカスタム要素の「custom-component」を配置してref属性に「child」という名前を付けています。

上記の例のコードを実行すると以下の画面が表示されます。

Vue.jsの$refsプロパティの使用例のサンプルコードの実行結果

上記の例では、コンポーネント要素に対してref属性を指定して$refsプロパティで参照していますが、$refsプロパティを使用した要素の取得はHTMLに標準で用意されている要素でも使用できます。

例えばinput要素を取得する場合は次のようになります。
HTML

JavaScript

ここでは、input要素のinputイベントをv-onディレクティブでonInputメソッドにバインドし、onInputメソッドでは$refsプロパティを利用してinput要素を参照して、input要素のvalueをコンソールログに出力しています。

$rootプロパティ

$rootプロパティは、コンポーネント階層のルート(トップ階層)のインスタンスを返します。

コンポーネントの階層が2階層の場合は$parentプロパティと同じインスタンスになります。

$rootプロパティの書式

$rootプロパティは、子コンポーネント側で以下のように使用します。

ルート要素のプロパティには$parentプロパティと同様に、dataオプションに定義したプロパティや、computedオプションに定義したプロパティを指定できます。

$rootプロパティの使用例

以下に$rootプロパティを使用してルートコンポーネントのデータを参照する例を示します。

HTML

JavaScript

ここでは、子コンポーネントと親コンポーネントとルートアプリケーションの3階層でコンポーネントを配置しています。
子コンポーネントでは、$rootプロパティでルートアプリケーションのデータを参照し、$parentプロパティで親コンポーネントのデータを参照しています。
親コンポーネントでは、$rootプロパティ、$parentプロパティでルートアプリケーションのデータを参照しています。

上記の例のコードを実行すると以下の画面が表示されます。

Vue.jsの$rootプロパティの使用例のサンプルコードの実行結果

$parent、$refs、$rootの利用について

props、$emitを利用しないデータのやり取りは一見便利ですが、コンポーネントの構造や階層が複雑になるとデータの流れが不明瞭になります。
$parent、$refs、$rootを利用したデータの交換は、props、$emitを利用したデータのやり取りができない場合や、props、$emitを利用することでパフォーマンスが悪くなる場合などに限り利用してください。
$parent、$refs、$rootによるデータの通信は、あくまでも例外的な手法になりますので、必要かどうかを検討してから利用してください。

Vue.js 入門 Tips 一覧