Laravel 5.4 ファーストステップ


## はじめに
[Laravelもくもく会@六本木](https://laracafe.connpass.com/event/49954/)に参加した際に、もくもく作っていたものを仕上げてみました。
これから、Laravelを使ってみようと思う方の役に立てれば幸いです。

## 事前準備
Laravel5.3から、PHP5.6.4以上が必要になりましたので、事前にインストールしておきます。

- PHP (5.6.4+)
- composer

## プロジェクト作成
```bash
$ cd /path/to/workspace
$ composer create-project --prefer-dist laravel/laravel laravel-first-step
```

## Welcomeページを表示
```bash
$ php artisan serve
```

http://127.0.0.1:8000 にアクセスして、下記のようにWelcomeページが表示されればOKです。

![laravel-welcome.png](https://qiita-image-store.s3.amazonaws.com/0/26422/049dc6d8-f641-5987-b85e-40a0646559e5.png "laravel-welcome.png")

## laravel-news.comのRSSフィードを表示する
素の状態から一歩進めて、新たにページを追加してみます。
`laravel-news.com`のRSSフィード（`https://feed.laravel-news.com/`）を表示するページを作ります。

### コントローラ
新たに下記のようにコントローラを作成します。

```php
// app/Http/Controllers/LaravelNewsController.php
namespace App\Http\Controllers;

use SimpleXMLElement;

class LaravelNewsController extends Controller
{
    public function show()
    {
        $xml = new SimpleXMLElement(file_get_contents('https://feed.laravel-news.com/'));
        $items = $xml->xpath('/rss/channel/item');

        return view('laravel-news', ['items' => $items]);
    }
}

```

### ルーター
`/laravel-news`でアクセスがあったら、作成した`LaravelNewsController`の`show`アクションにルーティングします。

```php
// routes/web.php

// 追記
Route::get('/laravel-news','LaravelNewsController@show');
```

### ビュー
Welcomeページのテンプレート`resources/views/welcome.blade.php`をベースに、ベーステンプレート`resources/views/layouts/app.blade.php`を作ります。

```html
<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
    	 <!-- 省略 -->
    </head>
    <body>
        <div class="flex-center position-ref">
            <div class="content">
                <div class="title m-b-md">
                    Laravel
                </div>
                <div id="app">
                    @yield('content')
                </div>
            </div>
        </div>
    </body>
</html>
```

ベーステンプレートを継承して、'content'セクションにRSSフィードを表示するためのテンプレートを記述します。

```
<!-- resources/views/laravel-news.blade.php -->
@extends('layouts.app')

@section('content')
    <div>
        @foreach ($items as $item)
        <div>
            <a href="{{ $item->link }}">{{ $item->title }}</a>
        </div>
        @endforeach
    </div>
@endsection
```

http://127.0.0.1:8000/laravel-news にアクセスして、下記のとおり、RSSフィードが表示されればOKです。

![laravel-news.png](https://qiita-image-store.s3.amazonaws.com/0/26422/a7a4069d-2136-ee5f-a646-ab3e3729c499.png "laravel-news.png")

## Vue.jsでRSSフィードをコンポーネント化してみる


### node.jsのインストール
`node.js`6.0以上が必要になりますので、あらかじめインストールしておきます。

```bash
$ node -v
v6.0.0
```

### npm install
必要なパッケージをインストールします。

```bash
$ npm install
```

### npm run dev
いったんビルドします。

```bash
$ npm run dev
```

下記のように、コンソールに出力されればOKです。

```
 DONE  Compiled successfully in 4007ms
                                                                                                                                                                                                                                                           Asset      Size  Chunks                    Chunk Names
  fonts/glyphicons-halflings-regular.eot?f4769f9bdb7466be65088239c12046d1   20.1 kB          [emitted]         
  fonts/glyphicons-halflings-regular.svg?89889688147bd7575d6327160d64e760    109 kB          [emitted]         
  fonts/glyphicons-halflings-regular.ttf?e18bbf611f2a2e43afc071aa2f4e1512   45.4 kB          [emitted]         
 fonts/glyphicons-halflings-regular.woff?fa2772327f55d8198301fdb8bcfc8158   23.4 kB          [emitted]         
fonts/glyphicons-halflings-regular.woff2?448c34a56d699c29117adc64c43affeb     18 kB          [emitted]         
                                                               /js/app.js   1.16 MB       0  [emitted]  [big]  /js/app
                                                             /css/app.css    146 kB       0  [emitted]         /js/app
                                                        mix-manifest.json  66 bytes          [emitted]         
```

### Vueコンポーネントの作成
RSSフィードの１アイテムを１つのコンポーネントにするために、`resources/assets/js/components/RssItem.vue`を作成し、下記のように記述します。
クリックしたら、'You are now leaving this website. Do you want to continue?'という確認メッセージを表示して、OKをクリックしたら別タブでリンク先を表示し、キャンセルをクリックしたら、何もしないようにします。

```html
<!-- resources/assets/js/components/RssItem.vue -->
<template>
    <div class="rss-item">
        <a :href="link" v-on:click="click" target="_blank">{{ title }}</a>
    </div>
</template>

<style>
    .rss-item {
        margin-bottom: 5px;
    }
</style>

<script>
    export default {
        props: ['link', 'title'],
        mounted() {
            console.log('Component mounted.')
        },
        methods: {
            click: function(e) {
                if (!window.confirm('You are now leaving this website. Do you want to continue?')) {
                    e.preventDefault();
                }
            }
        }
    }
</script>
```

### Vueコンポーネントを登録する
作成したVueコンポーネントを登録します。

```js
// resources/assets/js/app.js
Vue.component('rss-item', require('./components/RssItem.vue'));
```

### Viewテンプレートの変更
ViewテンプレートのRSSフィードの部分を下記のように書き換えます。

```
@extends('layouts.app')

@section('content')
    <div>
        @foreach ($items as $item)
        <rss-item link="$item->link" title="$item->title"></rss-item>
        @endforeach
    </div>
@endsection
```

### app.jsの読み込み（注意点あり）
BODYタグの閉じる直前に、`app.js`を読み込みさせると、`Uncaught TypeError: Cannot read property 'csrfToken' of undefined`が発生するので、下記のように、`csrf_token`をグローバル変数にセットします。

```
<!-- resources/views/layouts/app.blade.php -->
        <script>
            window.Laravel = <?php echo json_encode([
                    'csrfToken' => csrf_token(),
                ]) .PHP_EOL; ?>
        </script>
        <script src="/js/app.js"></script>
    </body>
</html>
```

#### 参考URL
- [Vuejs error: Cannot read property csrfToken of undefined](https://laracasts.com/discuss/channels/vue/vuejs-error-cannot-read-property-csrftoken-of-undefined/replies/314605)

### 動作確認
再度、`npm run dev`を実行して、動作確認します。
RSSのリンクをクリックして、確認メッセージが表示され、OKで別タブにリンク先のページが表示されればOKです。

![laravel-news-vue.png](https://qiita-image-store.s3.amazonaws.com/0/26422/efc6ba6f-a675-8724-01e6-4fac34159cef.png "laravel-news-vue.png")

（確認のために、右側にデベロッパーツールを表示しています。）

## おわりに
説明に使用したコードを[imunew/laravel-first-step](https://github.com/imunew/laravel-first-step)にて公開しておきますので、気になる方はcloneするなりにしてみてください。

また、ご意見ご指摘などありましたら、コメントいただけますと幸いです。

ではでは。