コンポーネントの属性には、基本的にはpropsオプションに定義さえている属性を指定します。
しかし、コンポーネントには、propsオプションで定義されていない任意の属性を渡すこともできます。
例えば、次のようなコンポーネントがあるとします。
1 2 3 4 5 6 7 8 9 |
const myComponent = { props: { myProps: { type: String, default: '' } }, template: '#component-template' } |
1 2 3 4 5 |
<script type="text/x-template" id="component-template"> <div title="コンポーネント側のタイトル" class="child"> {{myProps}} </div> </script> |
このコンポーネントを利用する親(アプリまたはコンポーネント)側では、以下のようになります。
1 2 3 4 5 6 7 8 9 10 |
Vue.createApp({ components: { 'my-component': myComponent }, data: function() { return { myPropsData: 'propsのデータ' } } }).mount('#app') |
1 2 3 |
<div id="app"> <my-component v-bind:my-props="myPropsData"></my-component> </div> |
上記のコードを実行すると、以下のHTMLが出力されます。
1 2 3 4 5 |
<div id="app" data-v-app=""> <div title="コンポーネント側のタイトル" class="child"> propsのデータ </div> </div> |
上記のコンポーネントの属性にmy-props(propsで定義されている属性)以外を指定します。
1 |
<my-component v-bind:my-props="myPropsData" title="指定したタイトル" class="parent" my-attribute="custom" ></my-component> |
ここでは、title属性とclass属性を指定しています。
上記のコード(HTMLテンプレート)を実行すると、以下のHTML が出力されます。
1 2 3 |
<div id="app" data-v-app=""> <div title="指定したタイトル" class="child parent" my-attribute="custom">propsのデータ</div> </div> |
title属性は、コンポーネントを利用する側で指定した値の「指定したタイトル」に上書きされています。
class属性では、コンポーネント側に指定されている「child」とコンポーネントを利用する側で指定した「parent」が設定されます。
propsで定義されていない属性は(非props属性)は、テンプレートのルート要素(ここではdiv要素)に付与されます。(title属性)
コンポーネント側で既に要素に定義されている属性は、原則としてコンポーネントを利用する呼び出し側から指定した値で上書きされます。(class属性)
ただし、class属性、style属性に関しては、既に定義されている属性値とマージされます。(my-attribute属性)
ここまでの例では、propsで定義されていない属性の指定について紹介しましたが、propsで定義されていない属性をルート要素に適用したくない場合(コンポーネント側で指定した値を上書きされたくない場合)もあるかと思います。
そんな時は、コンポーネント側にinheriAttrsプロパティオプションを定義して、値に「false」を指定します。
上記のサンプルコンポーネントであれば、以下のようになります。
1 2 3 4 5 6 7 8 9 10 |
const myComponent = { props: { myProps: { type: String, default: '' } }, template: '#component-template', inheritAttrs: false } |
9行目がinheritAttrsプロパティの指定になります。
このように指定することで、propsで定義されていない属性がルート要素に反映されなくなります。
1 2 3 |
<div id="app" data-v-app=""> <div title="コンポーネント側のタイトル" class="child">propsのデータ</div> </div> |
propsで定義されていない属性には、this.$attrs[名前]の形式でアクセスすることができます。
例えば上記の例で指定した「my-attribute」の値を取得する場合は、以下のようになります。
const value = this.$attrs[‘my-attribute’];
コンポーネントに指定したpropsで定義されていない属性の使用例を以下に示します。
ここでは、コンポーネント内に配置されているボタン(button要素)に属性を指定します。
1 2 3 |
<button v-bind="$attrs"> ボタン <button> |
指定した属性をコンポーネント内の要素に指定する場合はv-bindディレクティブを使用して指定することでまとめてバインドすることができます。
v-bindディレクティブについては、以下の記事を参考にしてください。