Vue.js(コンポーネント(データ渡し・イベント発火))(Laravel使用)

今回も[参考記事](https://cr-vue.mio3io.com/guide/chapter5.html)をもとに進めさせていただきます。
[コンポーネントの基本](https://jp.vuejs.org/v2/guide/components.html)こちらも見させていただきます。

##◆コンポーネント
コンポーネントは、ページの部品ごとに、html/js/cssをまとめちゃおうという考え方(管理がしやすく再利用性も高い)
Vue.jsにはコンポーネントをグローバル・ローカルに登録して利用することができます。

```:グローバルに登録
<body>
    <div id="sample">
        <sample></sample>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    Vue.component('sample', {
        template: '<h1>こんにちは</h1>'
    });
    const vue = new Vue({
        el: '#sample',
    });
</script>
```

```:ローカルに登録
<body>
    <div id="sample">
        <sample></sample>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    const sample = {
        template: '<h1>こんにちは</h1>'
    };
    const vue = new Vue({
        el: '#sample',
        components: {
            sample: sample
        }
    });
</script>
```

注意点として、コンポーネントはVueインスタンスを作成する前に定義してからVueインスタンスを作成することで、呼び出すことができます。また、コンポーネントでは、dataは複数のコンポーネントが同じオブジェクトを参照するという問題が発生するため、関数でないといけません。

```
data(){
 return{
 	message: 'こんにちは'
 }
}
```

##◆コンポーネント間のデータ渡し
[参考記事](https://jp.vuejs.org/v2/guide/components.html)

###親から子へデータを渡す

```
<body>
    <div id="sample">
        <child message="こんにちは"></child>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    Vue.component('child', {
        template: '<h1>@{{ message }}</h1>',
        props: ['message']
    });
    const vue = new Vue({
        el: '#sample',
    });
</script>
```

親から子へデータを渡すときに、子で受け取り変数はpropsで定義しておきます。
親で使うときにその変数に値を入れて渡します。
データ変数を渡したい場合、

```
<child :message="message"></child>
```

として、親のdataでmessageを定義してあげれば連動できます。
propsはデータ型も指定できます。[データ型一覧](https://cr-vue.mio3io.com/guide/chapter5.html#props%E3%81%AE%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8A%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B)
バリデーションのようなものと感じました。

###子から親のイベント発火
[参考記事](https://www.hypertextcandy.com/vuejs-components-introduction-emit-events)
子から親へデータを渡す際に必要となるのが<b>$emitとカスタムv-on</b>です。

```
<body>
    <div id="sample">
        <child @child-event="parentEvent"></child>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    Vue.component('child', {
        template: '<button @click="sendParent">クリック</button>',
        methods:{
            sendParent(){
                this.$emit('child-event');
            }
        }
    });
    const vue = new Vue({
        el: '#sample',
        methods:{
            parentEvent(){
                alert('親要素が反応しました。')
            }
        }
    });
</script>
```

子コンポーネントから見ていきますと、templateとしてclickイベントを備えたボタンを用意しました。
ボタンをクリックすると親コンポーネントの'child-event'が発火します。
親では、カスタムv-on(今回は省略して\@child-event)が発火すると、親メソッドのparentEventが発火するようにしています。
注意点としては、\@child-eventをキャメルケース(childEvent)で書いてしまうと動かなくなります。
<b>$emit</b>は第二引数を指定すると、好みのパラメータも渡せます。

##親子以外のコンポーネントのイベント発火
イベントバスと呼ばれるものを利用します。具体的は関係ない二つのコンポーネント用に共通のVueインスタンスを用意して、
イベントを発火させるほうに、\$emit、イベントを待ち受けるほうにmoutedもしくはcreatedのタイミングで、\$onを使用してイベントを検知します。[参考記事](https://se-tomo.com/2018/11/03/vue-js-%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E9%96%93%E3%81%AE%E9%80%9A%E4%BF%A1/)

##親から子のイベント発火
こちらも<b>$emitと$on</on>を使用しますが、違う点は<b>refと$refs</b>も使用します。この二つは、前回直接DOMをいじるときに使いました。使い方はそれと同じです。

```
<body>
    <div id="sample">
        <child ref="child"></child>
        <button @click="click">クリック</button>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    Vue.component('child', {
        template: '<h1>子コンポーネント</h1>',
        created: function(){
            this.$on('alert', function () {
                alert('子コンポーネントのイベント発火')
            })
        }
    });
    const vue = new Vue({
        el: '#sample',
        methods:{
            click(){
                this.$refs.child.$emit('alert');
            }
        }
    });
</script>
```

子コンポーネントでは、createdで\$onでイベント検知用にセット
それを親からrefと\$refsと\$emitを利用して呼び出しています。

##◆スロット
親コンポーネントと子コンポーネントででslotを埋め込むことにより、より部品的に再利用性の高いコンポーネントを作成することが可能です。

```:親
<child>
    <h1 slot="message">親コンポーネント</h1>
</child>
```

```子
<section class="child">
	<slot name="message">
		<h1>子コンポーネント</h1>
	</slot>
</section>
```

これで表示の時はデフォルトは「子コンポーネント」で「親コンポーネント」で文字を上書きしている。
データ変数で渡すことも可能