【Nuxt 2】インスタンスプロパティ
$slots
以下のように<slot>
を指定したコンポーネントを作成します。
<template>
<div>
<slot />
</div>
</template>
<template>
<parent>
<child />
<child />
<child />
</parent>
</template>
$slots
は、<slot>
内の要素をVNode
の配列として取得します。
slot
に名前をつけていない場合は$slots.default
、名前をつけている場合は$slots.name
で取得できます。
<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
はコンポーネント以外の要素も取得します。
コンポーネントのみに絞り込みたい場合は、componentInstance
がundefined
でないものを条件にします。
const components = this.$slots.default.filter((e) => !!e.componentInstance)
さらに特定のコンポーネントに絞り込みたい場合は、componentInstance
の情報を条件とします。
方法はいくつかありますが、ここでは言及しません。
componentInstance
は、その名の通り Vue コンポーネントのインスタンス(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>
内のコンポーネントのprops
やdata
の値を参照できたり、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
以下のようなコンポーネントを作成します。
<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
とすれば、parent
のVueComponent
が取得できます。
<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
を用いて同じ名前のプロパティを一括でバインドすることができます。
<template>
<child v-bind="$props" />
</template>
この時、子コンポーネント側は余分なプロパティを受け取らないようにinheritAttrs
をfalse
に設定するのが良いです。
<template>
<div>child</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
//....
}
}
</script>
$attrs
props
以外のコンポーネントに指定された属性を取得します。
'Vue 2'.x ではstyle
とclass
は対象外です。
Vue3.x からはstyle
とclass
も含まれます。
<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
でバインドされたイベントリスナーを取得します。
<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>