Vue.js-Laravelを使用して、ファイル管理について簡単に書いてみた

## なぜファイルを分けるのか
チュートリアルなんかでよく見かけることがありますが、<b>htmlとcssとJavaScriptとphpなどのコードを一つのファイルに書いてある例</b>があります。それは、チュートリアルとしては、一つのファイルでコードを書いたほうがページにまとめやすい・記事を見た人がみやすいなどの説明のためにそうしていることがほとんどです。

<b>実践の場ではそのまま使ってはいけないほうが多いと思います。</b>このページは記述量が少ないから、一つのファイルに書いてしまおうなどとしてしまうと、htmlとcssとJavaScriptとphpを同じファイルにあり、そのページのすべての部品の機能も同じファイルに記述された状態だと、この機能を足してほしいといったときに、どんどんファイルの記述量が肥大化していきます。問題としては、<b>コードを管理しにくかったり、初めて見る人が理解するのに時間がかかってしまうなどがあります。</b>
それをなるべく防ぐ方ためにファイルを分けます。ファイルを分けることを<b>抽象化</b>といいます。

ファイルの分け方もいろいろあります。例えば、Vue.jsでは<b>単一ファイルコンポーネント</b>という考え方があり、それはページの<b>部品ごとにファイルを分けて</b>、ページを作るときに、部品を一つずつ引っ張ってくることで、再利用性が高く、管理もしやすく、はじめてコードを見た人も理解がしやすくなります。他には、cssとJavaScriptとHtmlは別ファイルで管理するやり方などもあります。
今回はVue.jsを使って、下の例で、単一ファイルコンポーネントを体験してみます。

### 例をこなして体験してみる

Laravelプロジェクト配下で、コマンド<b>npm install</b>をたたいて、Vue.jsを使うための準備を整えます。
- [laravel Vue.js docker-compose環境構築](https://qiita.com/hekizi/items/1ea005af27f94dc50ff6)
- [laravelにVue.jsを入れる前の、5分間の事前学習](https://qiita.com/hekizi/items/6369590c8d0ce5b988f2)

環境が整えられたら、LaravelでVue.jsを使って、表示してみます。
(ファイル分けないで)(もともと用意されているwelcome.blade.phpを編集します)

```:welcome.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="UTF-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Vue.js</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css">
    <script src=" {{ asset('js/app.js') }} "></script>
</head>
<body>
    <div id="sampleDiv">
        <sample-component></sample-component>
    </div>
    <script>
        Vue.component('sample-component', {
            template:'<h1>今日も最高！！</h1>'
        });
        const vue = new Vue({
            el: '#sampleDiv',
        });
    </script>
</body>
</html>
```

Vue.jsのコンポーネントを使用して、このページではsample-componentという部品を利用しています。[Vue.jsコンポーネント](https://qiita.com/hekizi/items/55b8703f10f393d2ef7c)

###まず、bladeだけを分けてみます。

<b>構造</b>

```

    resources -- js
		      |
		      -- lang
		      |
		      -- sass
		      |
		      -- views -- layouts -- app.blade.php
			           |
			           -- welocome.blade.php
```

layoutsフォルダを作成し、その下にapp.blade.phpを作成します
(さらにheader.blade.phpとして、headerを別に分ける方法もあり)

```app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="UTF-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Vue.js</title>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css">
    <script src=" {{ asset('js/app.js') }} "></script>
</head>
<body>
    @yield('content')
</body>
</html>
```

もともとのwelocome.blade.phpからbodyの中身を@yield('content')に変えました。何がいいかというと、ページを複数作成するときに、app.blade.phpの中に記述していることは@extendsで再利用ができるという点で何回も記述しなくてすみます。
それでは、welcome.blade.phpを編集します。

```welcome.blade.php
@extends('layouts.app')
@section('content')
    <div id="sampleDiv">
        <sample-component></sample-component>
    </div>
    <script>
        Vue.component('sample-component', {
            template:'<h1>今日も最高！！</h1>'
        });
        const vue = new Vue({
            el: '#sampleDiv',
        });
    </script>
@endsection
```

@extendsで引き継ぐbladeを指定しています。先ほど@yieldで指定したところへ、@sectionから@endsectionまでの中身を挿入しています。画面を表示すると、先ほどと同じように「今日も最高！！」と表示されています。

### それでは、単一ファイルコンポーネントを利用してみます。

<b>先ほどの構造のjsディレクトリの詳細</b>

```
   js -- components -- ExampleComponent.vue
      |             |
      -- app.js     -- SampleComponent.vue
      |
      -- bootstrap.js
```

LaravelでVue.jsを使用する際にresources/js/app.jsをpublic/jsにコンパイル(出力)するため、<b>npm run dev</b>をたたきますが、npm run devは<b>webpack.mix.js</b>の内容を見て、出力してくれます。<b>webpackは複数のjsファイルが存在したとき、それの依存関係を解決し、一つのファイルにまとめてくれる便利なものです。</b>今回でいえば<b>npm run dev</b>をたたけば、一つのファイルにまとめてくれます。

<b>SampleComponent.vue作成</b>

```:SampleComponent.vue
<template>
    <p>
        {{message}}
    </p>
</template>
<script>
    export default {
        data: () => {
            return {
                message: '今日も最高！！'
            }
        }
    }
</script>
```

Vue.jsのコンポーネントの決まりとして、<template>タグの中に書きます。子コンポーネントなので、dataは関数です。
bladeでVue.jsのデータ変数を使う際は、@{{}}を使うのですが、.vueファイルのため{{}}内に書けます。

```:welocome.blade.php
@extends('layouts.app')
@section('content')
<div id="app">
    <sample-component></sample-component>
</div>
@endsection
```

id:appはもともと、app.jsに登録されているので、使用できます。idを変える場合はapp.jsに書くかwelocome.blade.phpでVueインスタンスを新たに作る必要があるため、今回記述量の少ないこちらを採用しました。
app.jsを編集します。

```:app.js
// Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('sample-component', require('./components/SampleComponent.vue').default);
```

exampleは使わないので、コメントアウトして、sample-componentを使うため、登録します。app.jsの下にid:appの記述があると思います。[require default](https://yuzu441.hateblo.jp/entry/2017/07/21/090000)

```コマンド
npm run dev
```
これでwelcome.blade.phpを表示すれば、表示されると思います。