10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravelから触るVue.js 知見まとめ

Last updated at Posted at 2019-05-31

npmとかのセットアップは割愛する。

また、ぼくはDockerコンテナでLaravelを動かしている。
Homestead環境の人ならホットリロードができるらしい。調べてみるといいかも。

ビルドする

開発ビルド
npm run dev
変更を監視して自動ビルド
npm run watch
製品ビルド
npm run prod

開発ビルドは警告やエラーがコンソールに表示される。
製品ビルドは警告がコンソールに表示されなくなる。

JavaScriptはブラウザによってしっかりとキャッシュされるので、ビルドしたらShift + Control + Rなどでキャッシュ削除リロードをしてあげよう。

実行結果がビルド前と変わらなくて悲しい思いをすることになる :scream:

Vueが働きかける範囲

resources/js/app.jsに記述されているこのコードで決まってる。

app.js
const app = new Vue({
    el: '#app'
});

初期状態ではHTMLタグのidがappの中でのみVue.jsが働きかけるようになっている。
Laravelが自動で生成したapp.blade.phpには<body>のすぐ中に<div id="app">があり、ほとんどの要素や継承したBladeテンプレートに対して働きかけるように最初からなっている。

特にいじらなくてよろし。

app.jsが読み込まれるタイミング

app.jsを読み込むコードにdeferという謎のワードが含まれている。

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

これはHTMLの読み込みと同時に非同期でJavaScriptも読み込んじゃって、HTMLの解析後にこのスクリプトを実行するという記述
そのため、app.jsの実行より先にapp.blade.phpやこれを継承するBladeテンプレート内に別個で記述したJavaScriptが実行されてしまうので、Vue.jsを始めとするライブラリがなにも使えない。

また、deferなどをつけた<script>タグの読み込みや解析の順番が毎回同じである保証は無いので、別ファイルで読み込ませるとかじゃなく、resources/js/app.jsに記述するかVue ComponentにJavaScriptを書いて、ビルドした結果public/js/app.jsにまとめられるようにすべきであろう

すなわちBladeテンプレートにJavaScriptを書くんじゃねぇってことなのかなって。

データバインディング

Vue.jsは変数とViewの要素を連携させるデータバインディングと呼ばれる機能がとても魅力的なフレームワークなんですって。

const app = new Vue({
    el: '#app',
    data: {
        message: 'こんにちは'
    }
});
<div id="app">
    {{ message }}
</div>
実行結果
<div id="app">
    こんにちは
</div>

JavaScriptで変数を変更すればHTMLもそれに従って勝手に表示が切り替わるし、input要素とかに変数を割り付ければ、HTMLからの入力に従ってJavaScriptの変数の値も変わる。

<input v-model="message" placeholder="入力してください">
<p>{{ message }}</p>

テキストフィールドに入力した内容がすぐにp要素の中に反映される。すごい。
フォーム入力バインディング — Vue.js

重ねて言うことになるが、JavaScriptの変数の内容にしっかり代入されているのでJavaScript側でフォーム内容を取得するような処理をわざわざしなくていい
何も面倒くさく無いじゃないか...!

Vue Component

HTMLタグを自作する的な気持ちでComponentなるものが作れる。
.vueファイルを別で作る方法をご紹介。

他にもいろいろ方法はあるらしいけど調べてない。

Componentを書く

Laravelがもとから用意してるサンプルを例にあげる。
PhpStormならファイル新規作成のとこからVue Cmponentが簡単につくれるようになってるので迷うことは無さそう。

ExampleComponent.vue
<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div class="card-body">
                        I'm an example component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

<template>タグ内は親要素をひとつのみ記述する。
2つ以上親を記述してしまうとビルドが通らなくなる。

エラーになる例
<template>
    <div>
       ...
    </div>

    <div>
       ...
    </div>
</template>

<script>
    ...
</script>

<template>の中には他のVue Componentを含めることもできる

めちゃくちゃ汎用的なComponentを作れたらそれはそれで別個にしたほうが再利用性が高まるからどんどん小分けにしたほうがいいね!

vue-routerなんかを使ったSPA構築のときはページそのものをVue Componentとして記述する。

<slot>タグ

VueComponent
<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>
HTML
<navigation-link url="/profile">
  Your Profile
</navigation-link>
レンダリング結果
<a
  v-bind:href="url"
  class="nav-link"
>
  Your Profile
</a>

シビれるなぁ...!!

Componentを登録する

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

require()には.vueのある相対パスを書いてあげる。

npmなどで導入したComponentならVue.use(/* なんかインポートしたときの名前 */);する。
ものによってはVue.component()で登録せにゃならんのもあるのでUsageを確認するのが吉。

こうすることでHTMLに<example-component></example-component>って書くと、Componentがバッと展開されるようになる。

Component全部を勝手に登録してもらうこともできる

resource/js/app.jsの20行目ぐらいにこんなコードがある。

/**
 * 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))

Docsコメントに記されている通りだが、コメントアウトされている最後の2行を使うことで**resource/js/配下の.vueファイルすベてを勝手にComponentとして登録してくれる。**
その際、ファイル名をPascalCaseであるとして、HTMLからケバブケースで指定することで使えるようになる。

Eg. ./components/ExampleComponent.vue -> <example-component></example-component>

便利だね!

触感まとめ

Vue.jsはjavascriptやjQueryでのDOM操作に苦労しまくった人がそれをめちゃくちゃ楽にやるためにつくったフレームワークって感じがした。

チェックボックスのチェックも変数を使って双方向データバインディング、CSSだってbool型変数と連携させクラスを付けたり消したり...
変数を変更すると意識せずともHTMLに即時反映されるから意識することが大幅に減ってとても楽に操作できて良いな...って思いました。

また、とてもナチュラルにHTMLとJavaScriptをセットで書けるからJavaScript書かなきゃな...って気持ちにならなくなりました。
これは良いものだ...!

日本語Docsがこれまた丁寧で、とても優しい良い子です。

参考

はじめに — Vue.js

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?