Vue.js inheritAttrsの挙動を調べる

https://vuejs.org/v2/api/#inheritAttrs

v2.4から inheritAttrsが使えるようになった。

By setting inheritAttrs to false, this default behavior can be disabled. The attributes are available via the $attrs instance property (also new in 2.4) and can be explicitly bound to a non-root element using v-bind.

inheritAttrs: falseを設定することで、属性を継承しなくなるようだ。実際にどのような挙動になるか試してみた。

js

// hrefにsrcを指定する<a>タグ基底コンポーネント
Vue.component('inherit-attrs-link', {
  inheritAttrs: true,
  props: ['src'],
  template: '<a :href="src">{{ src }}</a>'
})

Vue.component('not-inherit-attrs-link', {
  inheritAttrs: false,
  props: ['src'],
  template: '<a :href="src">{{ src }}</a>'
})

new Vue({
  el: '#app'
})

html

<div id="app">
    <!-- src, href の両属性を指定して結果を見る -->
    <inherit-attrs-link
      src="http://example.com"
      href="http://inherit-href.example.com"
      target="_blank"
    />
    <not-inherit-attrs-link
      src="http://example.com"
      href="http://inherit-href.example.com"
      target="_blank"
    />
</div>

Result

<!-- inheritAttrs: true -->
<a href="http://inherit-href.example.com" target="_blank">http://example.com</a>

<!-- inheritAttrs: false -->
<a href="http://example.com">http://example.com</a>
  • inheritAttrs: trueの場合
    • 親の属性が継承される。
    • コンポーネントで指定したhrefよりも親のhref指定が優先されている。
  • inheritAttrs: falseの場合
    • 親の属性が継承されないため、target属性がつかなかった。
    • コンポーネントで指定したhrefが反映された。

Source

See the Pen inheritAttrs by tic40 (@ccpzjoh) on CodePen.

v-bind="$attrs" を加えてみる

公式でv-bind="$attrs" を使う例が提示されていたので、そちらの挙動も確認してみる。

js

// v-bind="$attrs" をtemplateに加える
Vue.component('inherit-attrs-link', {
  inheritAttrs: true,
  props: ['src'],
  template: '<a v-bind="$attrs" :href="src">{{ src }}</a>'
})

Vue.component('not-inherit-attrs-link', {
  inheritAttrs: false,
  props: ['src'],
  template: '<a v-bind="$attrs" :href="src">{{ src }}</a>'
})

html

前例と同じ

Result

<!-- inheritAttrs: true -->
<a href="http://inherit-href.example.com" target="_blank">http://example.com</a>

<!-- inheritAttrs: false -->
<a href="http://example.com" target="_blank">http://example.com</a>
  • inheritAttrs: trueの場合
    • 同様の結果
  • inheritAttrs: falseの場合
    • v-bind="$attrs"を指定することで、実質属性が継承されるようになり、target属性が反映された。
    • v-bind="$attrs"でのhref指定(http://inherit-href.example.com)より、:href="src"の指定(http://example.com)が優先された。

Source

See the Pen inheritAttrs-bind$attrs by tic40 (@ccpzjoh) on CodePen.

まとめ

  • 最後の例のように、受け取るprops名と、付与する属性名が異なっている場合は、inheritAttrs: falseにして置いたほうが副作用がない。
  • 基底コンポーネントは、基本的には、inheritAttrs: false にしておいた方が良さそう