LaravelでQuasar Framework

最近の私は、LaravelのフロントエンドをVue.js(Vuex, Vue Router, Vuetify)で書いています。
Vuetifyはコンポーネントも豊富で便利ですが、たまには違うUIフレームワークを使ってみたくなりました。
調べたところ、Quasar Frameworkを見つけました。

> Build high-performance VueJS user interfaces in record time
> https://quasar.dev/

そこで今回は、LaravelでQuasar Frameworkを使ってUI実装してみます。
Laravelのバージョンは6.8.0です。

# 準備

```sh
$ composer create-project --prefer-dist laravel/laravel lara-quasar
$ cd lara-quasar
$ composer require laravel/ui --dev
$ php artisan ui vue --auth
$ yarn install
$ yarn add quasar --dev
$ yarn add quasar-extras --dev
$ yarn run watch
```

# Quasarの読み込み

デフォルトの`resources/js/bootstrap.js`の読み込みを削除します。

```resources/js/app.js
/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

window.Vue = require('vue');

/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))

Vue.component('example-component', require('./components/ExampleComponent.vue').default);


// Quasar Framework
import Quasar from 'quasar';
import 'quasar/dist/quasar.sass';
import 'quasar-extras/material-icons';

Vue.use(Quasar);


/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

const app = new Vue({
    el: '#app',
});
```

# ビューの変更

レイアウトを変更してみます。
`css/app.css`の読み込みは削除します。

```html:resources/views/layouts/app.blade.php 
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- CSRF Token -->
  <meta name="csrf-token" content="{{ csrf_token() }}">
  <title>{{ config('app.name', 'Laravel') }}</title>
  <!-- Scripts -->
  <script src="{{ asset('js/app.js') }}" defer></script>
  <!-- Fonts -->
  <link rel="dns-prefetch" href="//fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
</head>
<body>
  <div id="app">
    <q-layout view="hHh lpr fFf" container style="height:100vh">
      <q-header elevated>
        <q-toolbar>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo/svg/quasar-logo.svg">
          </q-avatar>

          <q-toolbar-title>Quasar Framework</q-toolbar-title>
        </q-toolbar>
      </q-header>

      <q-footer elevated>
        <q-toolbar>
          <q-toolbar-title>Footer</q-toolbar-title>
        </q-toolbar>
      </q-footer>

      <q-page-container>
        <q-page class="q-pa-md">

          @yield('content')

        </q-page>
      </q-page-container>
    </q-layout>
  </div>
</body>
</html>
```

`<q-layout>`の中に`<q-header>`、`<q-footer>`、`<q-page-container>`がある構造です。
`<q-layout view="hHh lpr fFf" container style="height:100vh">`の呪文のような`hHh lpr fFf`は、レイアウト構造の定義らしいです。
以下のリンク先でなんとなく理解してください。。。

https://quasar.dev/layout/layout#Understanding-the-%E2%80%9Cview%E2%80%9D-prop

ユーザ登録画面のビューは以下です。
ただしデータバインディングは実装していません。

```html:resources/views/auth/register.blade.php 
@extends('layouts.app')

@section('content')
<div class="row justify-center">
  <div class="col-4">
    <q-card>
      <q-card-section>
        <div class="text-h6">{{ __('Register') }}</div>
      </q-card-section>

      <q-separator></q-separator>

      <q-card-section>
        <q-input name="name" label="{{ __('Name') }}">
          <template v-slot:prepend>
            <q-icon name="person" />
          </template>
        </q-input>

        <q-input label="{{ __('Email') }}">
          <template v-slot:prepend>
            <q-icon name="email" />
          </template>
        </q-input>

        <q-input type="password" label="{{ __('Password') }}">
          <template v-slot:prepend>
            <q-icon name="lock" />
          </template>
        </q-input>

        <q-input type="password" label="{{ __('Confirm Password') }}">
          <template v-slot:prepend>
            <q-icon name="lock" />
          </template>
        </q-input>
      </q-card-section>

      <q-card-actions>
        <q-btn color="primary" label="{{ __('Register') }}"></q-btn>
      </q-card-actions>
    </q-card>
  </div>
</div>
@endsection
```

<img width="1190" alt="スクリーンショット 2020-01-08 17.05.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123511/37eb5e13-06ad-3567-4a00-5d1dc3a745c0.png">

なかなかいい感じではないでしょうか:thumbsup:
いまのところいちばん悩ましいのは、コンポーネントタグの接頭辞がqなので、キーボードのqをたくさん叩くために左手の小指が疲れることぐらいです:joy:（1やtabは苦ではないのに。。。）

# 参考URL

https://quasar.dev/
https://qiita.com/SatoTakumi/items/19222f6e74f53043d6a1