Vue.jsのコンポーネントについて勉強してみた！備忘録【応用編】

# はじめに
昨日に引き続き、コンポーネントについて学習し、ここで備忘録としてまとめてみます！
コンポーネントの勉強のきっかけとなった、タブの生成についても触れています！！

昨日の投稿↓
<a href="https://qiita.com/azunas/items/e8e246bdb72e3babea4a">
Vue.jsコンポーネント基本編</a>

今日も、いつも以上に強調させて頂きます、 備忘録です！！
テキスト読みながらメモした、自習ノートのような感覚で見てくださった方が良いかと思います！

# 動的コンポーネント
動的コンポーネントとは、**組み込みコンポーネント**の1種。
組み込みコンポーネントとは、特にこちらが記述したりしなくても利用できるコンポーネントで、
<component>要素を用います。これは、あらかじめこちらが用意した、複数のコンポーネントを動的に切り替えることが可能になります。
コンポーネントの入れ物(メタコンポーネント)のような存在です。

# 具体例1
例)3秒毎に切り替わるページ

```
// sample.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <title>sample</title>
    </head>
    <body>
        <div id='app'>
            <component v-bind:is='currentBanner' />
        </div>
        <script src='sampleVue.js'></script>
    </body>
</html>
```
コンポーネントを表示する場所を<component>要素で示しています。
表示するコンポーネントは、isで指定。ここでは、currentBannerが表示されるように設定されています。

```
// sample.js
Vue.component('sample-banner', {
    template: `<div class='banner'>
        <h3>サンプル</h3>
        <p>サンプルバナーサンプルバナー</p>
    </div>`
});

Vue.component('new-banner', {
    template: `<div class='banner'>
        <h3>new</h3>
        <p>newnewnew</p>
    </div>`
});

Vue.component('option-banner', {
    template: `<div class='banner'>
        <h3>option</h3>
        <p>optionoptionoption</p>
    </div>`
});

new Vue({
    el: '#app',
    created: function() {
        let that = this;
        this.interval = setInterval(function() {
            that.current = (that.current + 1) % that.components.length;
        }, 3000);
    },
    beforeDestroy: function() {
        clearInterval(this.interval);
    },
    computed: {
        currentBanner: function() {
            return this.components[this.current];
        }
    },
    data: {
      components: ['sample-banner', 
         'new-banner', 'option-banner'],
	  current: 0,
    }
});
```
上記の例では、まず、一番最初にVue.componentでコンポーネントを必要な分だけ作成。
new Vueの中で、3秒ごとに表示を切り替えるために、setIntervalで設定しています。
computedオプションでは、currentBannerプロパティを利用して、表示するべきコンポーネントを設定しています。
Dataオプションでは、componentsプロパティに、表示したいコンポーネントのリストを配列として入れておき、currentでは、そのコンポーネントたちが格納されている配列のインデックス番号を記述します。初期状態は、先頭のコンポーネントのため、currentプロパティに記述するインデックス番号は、0となります。

# 具体例2
例)タブパネルの作成

```
// sample.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <title>sample</title>
    </head>
    <body>
       <div id='container'>
            <ul>
                <li v-for='tab in tabNames'>
                    <a href='#' 
						v-on:click.prepend='onclick(tab)'>
                        {{ tabs[tab] }}
                    </a>
                </li>
            </ul>
            <keep-alive>
                <component v-bind:is='currentTab'></component>
            </keep-alive>
        </div>
        <script src='sampleTabVue.js'></script>
    </body>
</html>
```
コンポーネントを表示する場所を<component>要素で示しています。
表示するコンポーネントは、isで指定。ここでは、currentTabが表示されるように設定されています。
ここで、見慣れないタグが登場！<keep-alive>要素です。
これは、非アクティブになったコンポーネントを維持することが可能で、タブを行き来しても入力した値が消えないようにすることができます。ただし、リロードすると、消えてしまいます。

```
// sampleTabVue.js
Vue.component('tab1', {
    template: `<div class='tab'>
            <p>サンプルタブサンプルタブ</p>
            <label>Name:
                <input type='text' v-model='name' />
            </label>
            <input type='submit' value='go' />
        </div>`,
    data: function() {
        return {
            name: ''
        }
    }
});

Vue.component('tab2', {
    template: `<div class='tab'>
            <p>タブ2タブ2タブ2</p>
            <label>Name:
                <input type='text' v-model='name' />
            </label>
            <input type='submit' value='go' />
        </div>`,
    data: function() {
        return {
            name: ''
        }
    }
});

Vue.component('tab3', {
    template: `<div class='tab'>
            <p>tab3tab3tab3</p>
            <label>Name:
                <input type='text' v-model='name' />
            </label>
            <input type='submit' value='go' />
        </div>`,
    data: function() {
        return {
            name: ''
        }
    }
});

new Vue({
    el: '#container',
    methods: {
        onclick: function(tab) {
            this.current = tab;
        }
    },
    computed: {
        tabNames: function() {
            return Object.keys(this.tabs);
        },
        currentTab: function() {
            return this.current;
        }
    },
    data: {
      tabs: {
            'tab1': 'タブ1',
            'tab2': 'タブ2',
            'tab3': 'タブ3'
        },
		current: 'tab1'
    }
});
```
上記の例でも、まず、一番最初にVue.componentでコンポーネントを必要な分だけ作成。
new Vueの中で、methodsオプションにて、クリックすると、タブを切り替えるように設定します。
computedオプションでは、tabNamesプロパティで、タブ名を取得し、currentTabプロパティで、表示するべきコンポーネントを設定。
Dataオプションでは、tabsプロパティに、表示したいコンポーネントを、コンポーネント名をキー、表示するタブ名をプロパティとしてオブジェクトに格納し、currentでは、最初に表示するタブ名を記述。初期状態は、tab1(タブ1)を表示したいため、ここでは、’tab1’と記述。

以上となります！！
今回で一応、タブについての備忘録は終わりなんですが、また、Vue.jsで作ったポートフォリオサイトが完成次第、Vue CLIを用いたコンポーネントの利用方法の説明も兼ねて、投稿しますね！！

また、理解不足による、不備等ございましたら、コメントお願い致します！

# 参考文献
山田祥寛著『これからはじめるVue.js実践入門』(2019)