前置き
今回はcomponent①で解説した
自作コンポーネントを動的に変えられる
componentタグについての解説です✨🙋♀️
⬇️以降はこちら
【Nuxt.js】Nuxt文法編:component③動的コンポーネント
【Nuxt.js】Nuxt文法編:component④
⬇️公式ガイドはこちら
https://jp.vuejs.org/v2/guide/components.html#動的なコンポーネント
https://jp.vuejs.org/v2/guide/components-dynamic-async.html
ボタンで表示させる
コンポーネントを切り替えています🌟👀
条件つきのキャッシュ保存もやりますよ🙋♀️
非同期コンポーネントは
NuxtならasyncData
が使えるので
そちらをご覧ください👀
ただasyncData
は
pageコンポーネントでしか使えないので
通常のコンポーネントで使うなら
こちらを参考にすると良いかと思います🍎🙋♀️
https://qiita.com/hiroyukiwk/items/b83f52e6d899b06506cb
簡単な使い方
component v-bind:is
動的に複数のコンポーネントを
切り替えることができます🌟
切り替える度に
新しいインスタンスが作成され
キャッシュはクリアされてしまいます🌪
クリアされないようにするにはcomponent
タグをkeep-alive
タグで囲むのですが、
まずは簡単な使い方を理解しましょう💡
切り替えできることが分かれば良いので
コンポーネント名は安直に命名してます。
キャッシュ
保存する仕組みのことです💾
キャッシュのクリア
=保存ができない状態です🌪
Input1に入力した文字が
別のコンポーネントを表示させると
なくなってしまっていますね🍃
コード
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<template> <div class="page"> <button @click="changeComponent = 'Input1'">Input1</button> <button @click="changeComponent = 'Input2'">Input2</button> <button @click="changeComponent = 'Input3'">Input3</button> <component v-bind:is="changeComponent" class="box" > ここにコンポーネントが表示されます </component> </div> </template> <script> import Input1 from '~/components/Input1.vue' import Input2 from '~/components/Input2.vue' import Input3 from '~/components/Input3.vue' export default { data () { return { changeComponent: 'Input1', } }, components: { Input1, Input2, Input3, }, } </script> <style lang="scss" scoped> .page { .box { border: 1px solid orange; } } </style> |
) components
数字だけ変えたinputのコンポーネントを
3つ作成しています。
1 2 3 4 5 6 |
<template> <div class="input1"> <p>Input1</p> <input type="text"> </div> </template> |
値の受け渡し
props
なども使用できます⭕🙆♀️
inputでやるとややこしいので
ただのテキストをprops
で渡してみます。
画像Input1の
「親からテキストを渡す」の部分です。
コード
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<template> <div class="page"> <button @click="changeComponent = 'Input1'">Input1</button> <button @click="changeComponent = 'Input2'">Input2</button> <button @click="changeComponent = 'Input3'">Input3</button> <keep-alive include="Input3"> <component class="com" v-bind:is="changeComponent" :text="text" > ここにコンポーネントが表示されます </component> </keep-alive> </div> </template> <script> import Input1 from '~/components/Input1.vue' import Input2 from '~/components/Input2.vue' import Input3 from '~/components/Input3.vue' export default { data () { return { changeComponent: 'Input1', text: '親からテキストを渡す', } }, components: { Input1, Input2, Input3, }, } </script> |
) components
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<template> <div class="input1"> <p>Input1</p> <p> {{ text }}</p> <input type="text"> </div> </template> <script> export default { props: ['text'], } </script> |
keep-aliveでキャッシュを保存
component
タグをkeep-alive
タグで囲むだけで
あら不思議❗️🤭
キャッシュが保存されます💾
Input1に入力したテキストが
他のコンポーネントに切り替えた後でも
保存されていることが分かりますね♪
コード
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<template> <div class="page"> <button @click="changeComponent = 'Input1'">Input1</button> <button @click="changeComponent = 'Input2'">Input2</button> <button @click="changeComponent = 'Input3'">Input3</button> <keep-alive> <component v-bind:is="changeComponent" class="box" > ここにコンポーネントが表示されます </component> </keep-alive> </div> </template> <script> import Input1 from '~/components/Input1.vue' import Input2 from '~/components/Input2.vue' import Input3 from '~/components/Input3.vue' export default { data () { return { changeComponent: 'Input1', } }, components: { Input1, Input2, Input3, }, } </script> <style lang="scss" scoped> .page { .box { border: 1px solid orange; } } </style> |
keep-aliveにつけられる条件
Input3だけキャッシュされています💾keep-alive
に使える属性で
条件を絞ることができます🍊
公式:
https://vuejs.org/v2/api/#keep-alive
include
文字列, 配列, 正規表現(RegExp)の
指定が可能。
一致するコンポーネントのみが
キャッシュされます。exclude
文字列, 配列, 正規表現(RegExp)の
指定が可能。
一致するコンポーネントのみが
キャッシュされません。max
キャッシュする
コンポーネントインスタンスの最大数を指定します。
最大値に達した場合は
アクセスの古い順番に消えます。
コード
) pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<template> <div class="page"> <button @click="changeComponent = 'Input1'">Input1</button> <button @click="changeComponent = 'Input2'">Input2</button> <button @click="changeComponent = 'Input3'">Input3</button> <keep-alive include="Input3"> <component v-bind:is="changeComponent" class="box" > ここにコンポーネントが表示されます </component> </keep-alive> </div> </template> <script> import Input1 from '~/components/Input1.vue' import Input2 from '~/components/Input2.vue' import Input3 from '~/components/Input3.vue' export default { data () { return { changeComponent: 'Input1', } }, components: { Input1, Input2, Input3, }, } </script> <style lang="scss" scoped> .page { .box { border: 1px solid orange; } } </style> |
keep-alive-props
<nuxt />
や<nuxt-child />
で
キャッシュさせたい場合は
こんな感じでkeep-alive-props
属性を
バインドさせて使います。<nuxt-child keep-alive :keep-alive-props="{ include: ['Select'] }" />
ただ使っているのを
見かけたことがない
=使うシーンがあまりないので
そういうのもあるらしいくらいの認識で良いかもしれません⭕️
まとめ
- 動的にコンポーネントを切り替えるにはcomponentタグにis属性を使用する
- componentタグでもpropsを使った値の受け渡しなどが可能
- キャッシュを保存させるにはcomponentタグをkeep-aliveタグで囲む