top of page
執筆者の写真英伸 後

Laravel/Breeae の仕組み ~4 navigation.blade.phpの分析

1.navigation.blade.phpの分析


ユーザ登録直後に遷移するhttp://[URL]/dashboad画面のレンダリングを構成する主なファイルは以下の3つでした。

  1. dashboard.blade.php コンテンツの核をなすファイルです。子View -(A)

  2. layouts/app.blade.php Vが継承しているレイアウトです。親View -(B)

  3. layouts/navigation.blade.php (B) に挿入されるパーツです -(C)

このうち(B)に@includeされているnavigation.blade.phpにはWEBのいろいろな機能が実装されています。

この稿では、その内容を分析することで、Laravel Component の応用に生かしたいと思います。


2./dashboad画面のレンダリング


上記(A)(B)(C)のうち一番記述が長いのは(C)のnavigation.blade.phpですが、あくまで親レイアウトは(B)のapp.blade.phpです。

(B)のなかで(A)(C)がどのようにレンダリングされているかを確認します。


\views\layout\app.blade.php


********************

<!DOCTYPE html>

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>

//headの内容

</head>

<body class="font-sans antialiased">

<div class="min-h-screen bg-gray-100">

//@include('layouts.navigation') でnavigation.blade.phpの中身をレンダリング

<!-- Page Heading -->

<header class="bg-white shadow">

<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">

//{{ $header }}にdashboard.blade.php の<x-slot name="header">の中身をレンダリング

</div>

</header>

<!-- Page Content -->

<main>

//{{ $slot }}にdashboard.blade.php <x-slot name="header">以外の中身をレンダリング

</main>

</div>

</body>

********************


3.navigation.blade.php

\views\layout\navigation.blade.php 1/3

①<nav x-data="{ open: false }"・・・>

x-data= はJSフレームワークであるAlpine.jsに実装されているx-dataディレクティブと呼ばれるものです。

{ open: false }を指定することでopen というオブジェクトにfalseがオブジェクトデータとして格納され、このタグの子要素でopenが使えるようになります。

open オブジェクトはこの先の<button @click="open = ! open">等で利用されています。

②<x-application-logo />

ディレクティブ@component('components.application-logo')と同じ意味です。application-logoは4.で解説します

③<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">

ディレクティブ@component('components.nav-link')と同じ意味です。nav-linkに変数としてhref とactive を渡しています。

:active="request()->routeIs('dashboard')はオブジェクト$requestのプロパティであるrouteが'dashboard'と合致するか否かをrouteis関数でチェックしています。正の場合は1を、否の場合はnull を返します。

④<x-dropdown align="right" width="48">

ディレクティブ@component('components.dropdown')と同じ意味です。大き目のスロットを2つ('trigger','content')挟み込んでdropdownに渡しています。

先にこのスロットの中について解説します。

⑤<x-slot name="trigger">は@slot('trigger')と同意です。ここに挟まれた内容がdropdownに渡されてまた返ってきます。

⑥{{ Auth::user()->name }} 手軽に認証情報にアクセスして、ここではname属性の値を引用することができます。

裏側の動作は https://zenn.dev/ytakada/articles/8872a95417dc17 に詳しいです。


\views\layout\navigation.blade.php 2/3

⑦<x-slot name="content">は@slot('content')と同意です。ここに挟まれた内容がdropdownに渡されてまた返ってきます。

⑧<x-dropdown-link :href="route('profile.edit')">

ディレクティブ@component('components.dropdown-link')と同じ意味です。dropdown-linkに変数としてhrefを渡しています。

⑨onclick="event.preventDefault(); HTMLのボタンにonclick属性を付加し、クリックしたときに関数を実行することができます。

event.preventDefaultメソッドは、submitイベントの発生元であるフォームの送信動作を制御するJavaScriptメソッドです。

⑩this.closest('form').submit(); closest()関数は親要素を取得することができるメソッドです。さらに.submit()でフォームの送信処理をJavaScriptからコントロールしています。

 この要素を<Form>にする理由は今のところ不明です。Route::post()に回したいということなのでしょうか・・


\views\layout\navigation.blade.php 3/3

⑪<!-- Responsive Navigation Menu -->以下には はレスポンシブデザイン用のレイアウトが記述されています。

⑫<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden">

 :class はvue.jsに実装されているデータバインディングを適用するv-bind:class の省略記法で、オブジェクトを渡して CSS クラスを動的に切り替えます。

 ここでは'open'がtrueであれば"block"がCSS クラスに採用され、falseであれば"hidden"が採用されます


4.componentsファイルの解説

4-1. <!-- Logo --> ロゴのSV画像

\components\application-logo.blade.php

HTMLで<SVG>で囲むと、その中においてSVG(Scalable Vector Graphics)描画フォーマットで画像が描けます。SVGで描画できる図形は9種類で、それぞれ固有のタグがあります。Pathもその一つです。

<path>要素のタグの中d= 以下に座標や変曲点などの描画情報を記述します。


4-2. <!-- Navigation Links -->ナビゲーション表示部

@props(['active'])に:activeが渡されています。

($active ?? false)?'<A>':'<B>'; の構文は三項演算子、??はnull 合体演算子です。$activeがnullである場合はfalseを返し、それが三項演算子で<B>、$active=1の場合はtrueが返り<A>が$classesに代入されます。

絵では切れていますが

<A>

'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out'

<B>

'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out';

この後の<a>タグにマージすべき属性を使い分けています。

{{ $slot }}にはnavigationにおいて<x-nav-link> で囲まれた{{ __('Dashboard') }}がslotで入ります。

:href がnav-link内でどう展開されているかは不明です。


4-3. <!-- Settings Dropdown --> ドロップダウンメニュー

\components\dropdown.blade.php

①@props(['align' => 'right', 'width' => '48', 'contentClasses' => 'py-1 bg-white'])は定義されていますが、<x-dropdown>から渡された変数ではなく固定値が配列で定義されています。

②@php の中で'align'と'width'の分岐処理が行われていますが、上述のとおりここでは'align'も'width'も確定値なので、実質的な意味はありません。

 Breezeは「お手本」なので@propsで渡された変数をベタなPHPで処理することもできるというサンプルかもしれません。

③<div class="relative" x-data="{ open: false }" @click.outside="open = false" @close.stop="open = false">

 について、x-data="{ open: false }"が与えられているので、この子要素のopenの初期値はfalse になります。

 また@click.outside="open = false" でこの要素外のエリアをクリックした際にもopen = falseになります。@close.stop="open = false"の意味は調査中です。

④<div @click="open = ! open"> @click はvue.jsの書式です。この要素をクリックする都度openがfalse/true 反転します。

⑤{{ 'trigger' }}にnavigationの<x-slot name="trigger">が入ります。

⑥<div x-show="open" x-transition:enter="transition ease-out duration-200"・・・>

 x-show はこのタグの要素を見せたり隠したりします。"open"がtrueなら表示され、falseなら見えません。

 x-transition:enter= はx-show と同じタグ内でこの要素の表示させ方にアニメーション効果を加えます。

⑦{{ 'content' }}にnavigationの<x-slot name="content">が入ります。この要素は<div x-show="open" の子要素なので、openがtrueになれば表示され、falseになれば消えます。


4-4. ドロップダウンメニュのスタイルを追加

\components\dropdown-link.blade.php

*************************

<a {{ $attributes->merge(['class' => 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700

hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out']) }}>{{ $slot }}</a>

*************************

基本的にはnavigationの<x-dropdown-link ・・>のタグ属性に各種属性をマージしています。そしてnavigationの<x-dropdown-link ・・>に囲まれた中身を$slotに代入します。

<a>タグなのでhrefがあるはずなのですが、これはnavigationから渡されています。


4-5. <!-- Responsive Navigation Menu --> レスポンシブデザイン

layout.blade.php にはPC用の画面としての<Primary Navigation Menu>に対し、スマートフォン表示を行うための< Responsive Navigation Menu>が準備されています。

\components\responsive-nav-link.blade.php

基本的には4-2の解説と同じです


4-6. レンダリング結果
  1. dashboard.blade.php コンテンツの核をなすファイルです。子View -(A)

  2. layouts/app.blade.php Vが継承しているレイアウトです。親View -(B)

  3. layouts/navigation.blade.php (B) に挿入されるパーツです -(C)

  4. これらを補足するcomponents

これらのファイルによるレンダリングで以下HTMLが生成されます。

以上がユーザー登録に成功した際に遷移する「管理画面(Dashboard)」の解説です。












閲覧数:7回0件のコメント

Comments


bottom of page