nuxt.svg

【Nuxt 2】インスタンスプロパティ

Nuxt2

$slots

以下のように<slot>を指定したコンポーネントを作成します。

Parent
<template>
  <div>
    <slot />
  </div>
</template>
使用例
<template>
  <parent>
    <child />
    <child />
    <child />
  </parent>
</template>

$slotsは、<slot>内の要素をVNodeの配列として取得します。 slotに名前をつけていない場合は$slots.default、名前をつけている場合は$slots.nameで取得できます。

Parent
<template>
  <div>
    <slot />
  </div>
</template>

<script>
export default {
  mounted() {
    console.log(this.$slots.default)
  }
}
</script>
出力結果
(5) [VNode, VNode, VNode, VNode, VNode]
0: VNode
  asyncFactory: undefined
  asyncMeta: undefined
  children: undefined
  componentInstance: VueComponent {_uid: 57, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  componentOptions: {propsData: {…}, listeners: undefined, tag: "child", children: undefined, Ctor: ƒ}
  context: VueComponent {_uid: 55, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  data: {on: undefined, hook: {…}, pendingInsert: null}
  elm: div
  fnContext: undefined
  fnOptions: undefined
  fnScopeId: undefined
  isAsyncPlaceholder: false
  isCloned: false
  isComment: false
  isOnce: false
  isRootInsert: false
  isStatic: false
  key: undefined
  ns: undefined
  parent: undefined
  raw: false
  tag: "vue-component-15-Child"
  text: undefined
  child: (...)
  [[Prototype]]: Object

$slotsはコンポーネント以外の要素も取得します。 コンポーネントのみに絞り込みたい場合は、componentInstanceundefinedでないものを条件にします。

const components = this.$slots.default.filter((e) => !!e.componentInstance)

さらに特定のコンポーネントに絞り込みたい場合は、componentInstanceの情報を条件とします。 方法はいくつかありますが、ここでは言及しません。

componentInstanceは、その名の通り Vue コンポーネントのインスタンス(VueComponent)です。 つまり、コンポーネントの情報を持つオブジェクトです。 以下がその情報になります。 これは一例ですので、環境などによって情報の差異があることに注意してください。

componentInstance(VueComponent)の例
componentInstance: VueComponent
  $attrs: (...)
  $children: []
  $createElement: ƒ (a, b, c, d)
  $el: div
  $listeners: Object
  $options: {parent: VueComponent, _parentVnode: VNode, propsData: {…}, _parentListeners: {…}, _renderChildren: undefined, …}
  $parent: VueComponent {_uid: 21, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  $refs: {}
  $root: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
  $scopedSlots: {$stable: true, $key: undefined, $hasNormal: false}
  $slots: {}
  $vnode: VNode {tag: "vue-component-15-Child", data: {…}, children: undefined, text: undefined, elm: div, …}
  do: ƒ ()
  text: (...)
  _c: ƒ (a, b, c, d)
  _data: {__ob__: Observer}
  _directInactive: false
  _events: {}
  _hasHookEvent: false
  _inactive: null
  _isBeingDestroyed: false
  _isDestroyed: false
  _isMounted: true
  _isVue: true
  _name: "<Child>"
  _props: {}
  _renderProxy: Proxy {_uid: 22, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  _routerRoot: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
  _self: VueComponent {_uid: 22, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
  _staticTrees: null
  _uid: 22
  _vnode: VNode {tag: "div", data: undefined, children: Array(1), text: undefined, elm: div, …}
  _watcher: Watcher {vm: VueComponent, deep: false, user: false, lazy: false, sync: false, …}
  _watchers: [Watcher]
  $axios: (...)
  $config: (...)
  $content: (...)
  $data: (...)
  $gtag: (...)
  $icon: (...)
  $isServer: (...)
  $nuxt: (...)
  $props: Object
  $route: (...)
  $router: (...)
  $ssrContext: (...)
  _hasMetaInfo: (...)
  get $attrs: ƒ reactiveGetter()
  set $attrs: ƒ reactiveSetter(newVal)
  get $listeners: ƒ reactiveGetter()
  set $listeners: ƒ reactiveSetter(newVal)
  get _hasMetaInfo: ƒ ()
  [[Prototype]]: Vue

見ていただくとわかる通り、かなりのプロパティがあります。 大雑把に分けると以下のようになります。

  • $[prop]:インスタンスプロパティ、カスタムプロパティ
  • _[prop]:すべてのコンポーネントが持つ共通のプロパティ
  • [prop]:コンポーネント独自のプロパティなど(props, data, methods,…)

componentInstanceにアクセスすれば、<slot>内のコンポーネントのpropsdataの値を参照できたり、methodsに定義されたメソッドを実行することができます。

注意してほしいことは、$slotsで参照した情報はリアクティブでないことです。 そのため、参照した情報をcomputedで使用することはやめましょう。

$refs

$refsは、ref属性を設定した要素を参照するためのものです。 詳細はこちらの記事に記載しています。

<template>
  <div>
    <child ref="child" />
  </div>
</template>

<script>
export default {
  mounted() {
    this.$nextTick(() => {
      console.log(this.$refs.child)
    })
  },
}
</script>

$children

以下のようなコンポーネントを作成します。

Parent
<template>
  <div>
    <child />
    <slot />
  </div>
</template>

$childrenは、自身の中で使用しているコンポーネントをVueComponentの配列として取得します。 これは<slot>で指定したコンポーネントも対象となります。 つまり、以下のように使用した場合は 4 つVueComponentが取得できます。

<template>
  <parent>
    <child />
    <child />
    <child />
  </parent>
</template>

$childrenは Vue3.x から廃止されるようです。 正直$slots$refsがあれば事足ります。

$parent

親のVueComponentを取得します。 child$parentとすれば、parentVueComponentが取得できます。

<template>
  <parent>
    <child />
  </parent>
</template>

$el

コンポーネントの要素を取得します。 自身で使用することはないと思いますが、$slotsなどでVueComponentを参照した場合に使用します。 例えばルート要素のクラス名を参照したり、スタイルを適用したりできます。

this.$slots.default.filter(
  (e) =>
    !!e.componentInstance && e.componentInstance.$el.className.includes('child')
)

$props

コンポーネントのpropsの情報を取得します。 使用例として、v-bindを用いて同じ名前のプロパティを一括でバインドすることができます。

Parent
<template>
  <child v-bind="$props" />
</template>

この時、子コンポーネント側は余分なプロパティを受け取らないようにinheritAttrsfalseに設定するのが良いです。

Child
<template>
  <div>child</div>
</template>

<script>
export default {
  inheritAttrs: false,
  props: {
    //....
  }
}
</script>

$attrs

props以外のコンポーネントに指定された属性を取得します。 'Vue 2'.x ではstyleclassは対象外です。 Vue3.x からはstyleclassも含まれます。

Parent
<script>
export default {
  props: {
    text: ''
  },
  mounted() {
    console.log(this.$attrs)
  }
}
</script>
呼び出し
<parent text="hoge" fuga="fuga" piyo="piyo" />
出力結果
{fuga: "fuga", piyo: "piyo"}

$listeners

v-onでバインドされたイベントリスナーを取得します。

Parent
<script>
export default {
  mounted() {
    console.log(this.$listers)
  }
}
</script>
呼び出し
<parent @click="hoge" @change="piyo" />
出力結果
{click: f, piyo: f}

$listenersは、Vue3.x から廃止されます。 代わりに$attrsで取得するようになります。

_uid

インスタンスプロパティではないですが、知っておくと便利なので記載しておきます。

_uidはコンポーネントインスタンスごとに一意となるように割り当てられた値です。 例えばチェックボックスのコンポーネントを作成する場合、<label>との紐付けに使用できます。

<template>
  <div>
    <inupt type="checkbox" :id="_uid" v-model="value">
    <label :for="_uid">Checkbox</label>
  </div>
</template>