Vue+Pug:JavaScriptで作成した変数をPugで読込もうとしたが出来ないらしい

Vue+Pug:JavaScriptで作成した変数をPugで読込もうとしたが出来ないらしい

Vue+Pug:JavaScriptで作成した変数をPugで読込もうとしたが出来ないらしい

そもそもPUGって何?という方はこちらを参考に。
JSで作成した配列を基にしてPUGでリンクリストを書こうと思い当初、下のようなルートを考えていました。

  1. JavaScriptでリンクの配列を作成
  2. 作成した配列をPUGで読み込む
  3. PUGでeach in ループを回してリンクリストを出力

このルート、どうやら出来ないらしいです。と言う事で、目的の画面を作成するための四苦八苦です。

まずは前提条件から

現在こんなディレクトリ構成でVue.jsのフロントを作成しています。
今回はこの中の太字にした個所についての話です。

Vueプロジェクト/
├── node_modules
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   ├── router/
│   ├── store/
│   └── views/
│       └── Home/
│           ├── Home.js
│           ├── Home.pug
│           ├── Home.scss
│           └── Home.vue
├── App.vue
├── main.js
└── registerServiceWorker.js

例えば『画面サイズを取得してリンクの数をコントロールをしよう』と思い、viewsのHome.jsにこんなコードを書いたとします。※ブラウザの画面サイズを取得、横幅に合わせてリンクの要素数を増減する

こんな感じで記載すると、スマホの場合(一番上)は要素を3つに、タブレットやスクウェアPCの場合は4要素に、ワイド画面の場合は6要素にと可変するメニューの土台が作成できます。

JSで作った変数をPUGに持っていこうとしたが出来ないことが判明

折角のPugなのだからとHome.pug内で【 each in 】ループを行おうと思っていたのですが、エラー/エラー/エラー。

色々操作してみた結果【JavaScript から PUGへの変数の引き渡し】が課題だとわかり調べてみるとこんな記事が。
pugでJavascriptから引数objectを渡そうとするもエラーでできず

なるほど、そもそも出来ないのか。だとしたらやりたい事を別の方法での実装を考えます。

PUGで出来ないならVueで展開すればよくね?

プログラムの面白いのがこういう「他の方法を考えられる」という点ですよね。
Pugで出来ないならほかの手段を使えば良いのです。
パッと思いつくのはこんな所でしょうか。

  1. JavaScriptでHTMLスクリプトまで作ってしまいDOMで配置する
  2. JavaScriptは配列のみ作成し、Vueで forループを回す
  3. Pug内に分岐用の配列(今回の例だと3タイプ)を用意、JavaScriptで分岐フラグを掃き出し、Vueの If(またはCase)で展開
  4. JavaScriptで分岐用の配列と分岐用フラグを用意、Vueの If(またはCase)で展開
  5. JavaScriptで分岐フラグを掃き出し、Vueの If(またはCase)で配列の要素までゴリゴリ書く

PUGでのループに拘らなければ手段はいくつもあります。

今回は2の方法を採用

まぁね、先に配列作ってるし作り変える手間が減りますからね。

Home.vueでこんな形で記載すればリンクを展開してくれます。

チョット解説

■2行目:『 v-for=” ■ in ■s” 』

これがVueの each in です。Laravelで言う所のforeach。
他の言語に慣れていると悩むところは【ループを書く場所】だと思います。
Vueの場合は「繰り返したいタグの場所で記載する」ことになります。
Laravelとかだと<ul>と<li>の間にループ処理書きますが、そうではないので悩んだ末に<ul>に書いてしまう事がないように覚えておきましょう。

■3行目:『 <router-link :to=”{path:vl.url}” > 』

今回この処理が一番悩みました。

{{vl.url}}とするとテキストを吐き出すので、ついつい <router-link :to=”{{vl.url}}”>としてしまいますが、これだとエラーが発生します。

router-linkのto=に変数を渡す場合は次のルールに従い記載していきます。

  1. 文字列変数を入れる場合(※今回の場合)は “{ path : 文字列変数 }” とする
  2. 固定文字列を入れる場合は “{ name : ‘固定文字列’ }” とする
  3. routerに引数登録がある場合はその値を宣言して配置する (例:”{params: {id: task.id, edit_id: 10}}” ※id / edit_id をrouter.js で宣言している場合、その箇所に値を格納する [ path: ‘/:id/edit/:edit_id’, ] )
  4. 変数や定数をカンマで続けた場合、スラッシュで続けた値に変換される

折角なので、先程作成したVueスクリプトをPUGに変換してみる

Home.vueに書いた先程のScriptをPUGで書いてみたいと思います。

まぁね、そこまでしてPUGで書く必要があるかって感じになるのは重々承知してますが。
とりあえず、こんな形にすればPUGにJavaScriptの引数を渡すのと同じ結果の実装がPUGを使って可能です。

まとめ

Vue×Pug×JS×SCSSという組み合わせのページ作成をすることがあると思います。
そして、沢山のライブラリが絡めば「どうしても超えられない(出来ない)事」も当然出てきます。
そんな時は別ルートを考えると解決方法が必ずあるのがプログラムの醍醐味。
楽しいですね。