【Laravel】変数をjsファイルで簡単に使えるようにするには?

この記事は約7分で読めます。

一般的なやり方だと…

▼Controller側

public function index()
    {
        $js_variable = 'js変数';
        return view('injections.index', compact('js_variable'));
    }

▼HTML側

@extends('layouts.app')

@push('script')
    <!-- 以下3行がControllerから受け取った、変数を定義しているところ -->
    <script>
        const JS_VARIABLE = `{{ $js_variable }}`;
    </script>
    <!-- 以下のjsファイルは後述 -->
    <script src="{{ asset('js/index.js') }}"></script>
@endpush

▼jsファイル

// jsの即時関数だね
(function() {
    console.log(JS_VARIABLE );
})();

といった具合に、一回HTMLでControllerから受け取った変数を定義してjsファイルでそれを使うといった処理をいちいち書かないといけない。

jsで使う変数が増えるとHTMLにjsの変数定義行が多くなって見づらいし、それはHTMLで使うものではないから、HTML目線からするとなんか邪魔な感じするよね。。。

どうするのがいいか?

結論

Controllerで定義したjs変数をHTMLに渡してくれるライブラリを使う。

composer require laracasts/utilities

これは実際の処理は、一般的なやり方と同じだけど、このライブラリに則した簡単な設定(後述)をすると、Controllerにjs変数を定義しただけで、jsファイルでその変数を使えるようになるというもの!

詳細説明

  • composerでインストール
composer require laracasts/utilities
  • config/app.phpに以下のServiceProviderを追加
'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        ~~~ 略 ~~~
        /** jsでlaravel変数を使えるようにする */
        Laracasts\Utilities\JavaScript\JavaScriptServiceProvider::class

    ],
  • ライブラリの設定ファイルを表示する
php artisan vendor:publish --provider="Laracasts\Utilities\JavaScript\JavaScriptServiceProvider"

結果 > Copied File [/vendor/laracasts/utilities/src/config/javascript.php] To [/config/javascript.php]Publishing complete.

  • 設定ファイルを開く
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | View to Bind JavaScript Vars To
    |--------------------------------------------------------------------------
    |
    | Set this value to the name of the view (or partial) that
    | you want to prepend all JavaScript variables to.
    | This can be a single view, or an array of views.
    | Example: 'footer' or ['footer', 'bottom']
    |
    */
    // ↓views/footerにcontroller側で定義した変数を記述するという意味
    'bind_js_vars_to_this_view' => 'footer',

    /*
    |--------------------------------------------------------------------------
    | JavaScript Namespace
    |--------------------------------------------------------------------------
    |
    | By default, we'll add variables to the global window object. However,
    | it's recommended that you change this to some namespace - anything.
    | That way, you can access vars, like "SomeNamespace.someVariable."
    |
    */
    // 変数スコープ
    'js_namespace' => 'window'
];

この設定ファイルを見ると、どうやらfooter.phpが必要だね。

まだ、ないって人はresources/views/footer.phpを作る!

もうfooterはあるよって人はそのフッターへのパスを記述しよう。

例えば、resources/views/layout/footerにある場合は、以下のように記述する。

‘bind_js_vars_to_this_view’ => ‘layout/footer’,

  • footerファイルをHTML側でincludeする。
 @include ('footer')

ここまででライブラリの設定完了です。

最後に、Controller側の処理を変更すると、以下のような形になります。

▼Controller側

public function index()
{
    // ライブラリはFacadeとして登録されているので、\JavaScriptとする
    \JavaScript::put([
        'js_variable' => 'js変数',
    ]);

    return view('index');
}

▼HTML側

    <script src="{{ asset('js/index.js') }}" defer></script>

</body>タグ直上に書かないのであれば、defer属性は必須です!

▼jsファイル

// jsの即時関数だね
(function() {
    console.log(js_variable);
})();

まとめ

いかがでしたでしょうか
Controller側からHTMLに渡して、HTML側で受け取った変数を展開してjs変数に定義するという手順がかなりスッキリし他のではないでしょうか?

ライブラリインストール

ServiceProvider登録

設定ファイルにfooterへのパスを記述

(なければfooter.blade.phpを作成)

Controller側で\JavaScriptファザードを使ってHTML側へpush!

設定さえ済んでしまえば、Controller側の記述だけで済むので非常に楽ですね。
しかし、

結局は、一般的なやり方にもあるように、HTML側で変数定義しているのと変わりはないので、秘匿性の高い情報はcontroller側で弾いてあげるとかの対応は必要だと思います。
例えば、Userモデルからリクエストを送ってきたユーザーのIDから情報取得して、丸ごと変数にぶち込むといったことは避けた方がいいです。

以上、Laravelでjs変数を簡単に使えるようにするには?でした。
なにか、もっといい方法や問題点等ありましたらご教示いただけますと幸いです!

コメント