在 Web 开发中会遇到许多页面布局很相似,甚至许多页面的头部和底部显示都是一样的,比如我的这个博客应用,前端所有展示页面的头部和底部就是一样的。

如果每个页面都要重复写这些代码,会导致代码不够灵活、简洁,当然谁也不愿意做重复工作。为了使后面的开发更容易,更好的维护代码,需要设置一个模版,这个模版包含一些通用的视图,页面只要继承这个模版,就拥有模版里面的内容。

Laravel 的 Blade 模板支持继承,这意味多个子视图可以共用父视图提供的视图模板,接下来就是使用 Blade 设置模版。

布局

resources/views目录下创建一个 layouts目录,在layouts目录下添加三个文件:

  1. 模版文件(子视图需要继承的父视图)- app.blade.php
  2. 通用头部 - header.blade.php
  3. 通用底部 - footer.blade.php

1. 模版

resources/vews/layouts/app.balde.php

  1. <!DOCTYPE html>
  2. <html lang="{{ app()->getLocale() }}">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <!-- CSRF Token -->
  8. <meta name="csrf-token" content="{{ csrf_token() }}">
  9. <title>@yield('title','SevDot')|SevDot-关注独立开发和自由职业</title>
  10. <link rel="shortcut icon" type="image/x-ico" sizes="16x16" href="/favicon.ico"/>
  11. <meta name="author" content="sevdot(sevdot8@gmail.com)"/>
  12. <meta name="keywords" content="SevDot,独立开发,自由职业"/>
  13. <meta name="description" content="崇尚独立开发,追求自由职业,记录在独立自由上的探索。"/>
  14. <link href="{{ asset('css/app.css') }}" rel="stylesheet">
  15. </head>
  16. <body>
  17. @include('layouts.header')
  18. @yield('content')
  19. @include('layouts.footer')
  20. </body>
  21. </html>

在模版中引入了头部和底部,继承这个模版的页面就会包含这两部分,使用 @include引入视图,@include接受两个参数,第一个参数是视图的路径,第二参数是数据,这里不需要给视图传输数据,所以省略了第二个参数。

  1. @include('layouts.header')

@yield是占位区域,这里的内容将由继承自模版的视图文件定义,模版文件中定义了两个占位,分别是标题的部分内容和页面的主要内容区域:

@yield('title','SevDot')|
@yield('content')

@yield接受两个参数,第一个是区域名称,第二个是默认内容,继承模版的视图没有填充的话,由该参数填充。

2. 通用头部

resources/vews/layouts/header.balde.php

<nav id="navbar" class="navbar is-link has-shadow">
    <div class="container is-max-widescreen">
        <div class="navbar-brand">
            <a class="navbar-item" href="">
                <span class="logo title is-3 has-text-white">SevDot</span>
            </a>
            <div id="navbarBurger" class="navbar-burger burger" data-target="navMenu">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </div>
        <div class="navbar-menu" id="navMenu">
            <div class="navbar-start">

            </div>
            <div class="navbar-end">
                <a href="" class="navbar-item">首页</a>
                <a href="" class="navbar-item">项目</a>
                <a href="" class="navbar-item">博客</a>
                <a href="" class="navbar-item">关于</a>
            </div>
        </div>
    </div>
</nav>

3. 通用底部

resources/vews/layouts/footer.balde.php

<footer class="footer">
    <div class="has-text-centered">
        <a class="has-text-link" href="">项目</a>
        <a class="has-text-link" href="">博客</a>
        <a class="has-text-link" href="">关于</a>
    </div>
    <div class="has-text-centered">
        <span>©SevDot 2022. All rights reserved.</span>
        <a href="http://www.miitbeian.gov.cn/" target="_blank">滇ICP备17004667号-3</a>
    </div>
</footer>

使用模版

现在需要修改首页、联系页和关于页面,让其继承模版视图。使用@extends并通过传参来继承父视图layouts/app.balde.php的视图模板。

@extends('layouts.app')

使用@section@stop 代码来填充父视图的@stop区块,所有包含在@section@stop中的代码都将被插入到父视图的content区块。

@section('content')
  <h1>主页</h1>
@stop

1. 首页

resources/views/pages/root.balde.php

@extends('layouts.app')

@section('content')
    <section class="hero is-link">
        <div class="hero-body">
            <div class="has-text-centered mt-2">
                <h1 class="title is-4">独立自由</h1>
                <p class="subtitle is-6">崇尚独立开发,追求自由职业。</p>
                <a href="" class="button is-outlined is-info">联系</a>
            </div>
        </div>
    </section>
    <section class="section">
        <div class="container is-max-widescreen">
            <div class="columns">
                <main class="column is-9">
                    <div class="box">
                        <h2 class="title is-5">最新文章</h2>
                        <hr class="mt-1 mb-3">
                        @if($articles->isEmpty())

                        @else
                            @foreach($articles as $key=>$value)
                                <div class="box is-flex">
                                    <a class="is-flex" href="" title="{{$value->title}}">
                                        <time>{{$value->created_at->toDateString()}}</time>
                                        <span style="margin: 0 5px;">|</span>
                                 <div class="box has-text-centered has-text-warning-dark">~~暂无数据,敬请期待~~</div>
                    </div>
                </main>
                <aside class="column is-3">
                    <div class="box">
                        <p class="has-text-centered">站长:<a href="{{url('/contact')}}" target="_blank">SevDot</a></p>
                        <hr>
                        <div class="is-flex is-justify-content-center">
                            <figure class="image is-96x96">
                                <img class="is-rounded" style="" src="{{asset('images/sevdot_avatar.jpg')}}" alt="SevDot 的头像">
                            </figure>
                        </div>
                        <hr>
                        <div class="has-text-centered">
                            <a href="" class="button is-light"><span class="icon"><i
                                        class="fa fa-github"></i></span></a>
                            <a href="" class="button is-info"><span class="icon"><i class="fa fa-weibo"></i></span></a>
                            <a href="" class="button is-success"><span class="icon"><i class="fa fa-weixin"></i></span></a>
                        </div>
                    </div>
                    <div class="box">
                        <h2 class="title is-5 has-text-centered has-text-success">微信公众号</h2>
                        <hr>
                        <img src="{{asset('images/sevdots.png')}}" alt="">
                    </div>
                </aside>
            </div>
        </div>
    </section>
@stop

2. 联系页

resources/views/pages/contact.balde.php

@extends('layouts.app')
@section('title')
    联系
@stop
@section('content')
<section class="section">
    <div class="columns">
        <div class="column is-offset-4 is-4">
            <div class="box">
                <div class="message is-success">
                    <div class="message-body has-text-centered">
                        <i class="fa fa-warning"></i> 添加微信请道明来意,谢谢!
                    </div>
                </div>
                <div class="is-flex is-justify-content-center">
                    <figure class="image is-300x300">
                        <img src="{{asset('/images/wechat.jpeg')}}" alt="">
                    </figure>
                </div>
            </div>
            <div class="box">
                <h2 class="title is-4">公众号</h2>
                <hr>
                <figure class="image">
                    <img src="{{asset('images/sevdots.png')}}" alt="">
                </figure>
            </div>
        </div>
    </div>
</section>
@stop

3. 关于页

resources/views/pages/about.balde.php

@extends('layouts.app')
@section('title')
    联系
@stop
@section('content')
    <section class="section">
        <div class="container is-max-widescreen">
            <div class="columns">
                <div class="column is-offset-2 is-8">
                    <div class="box">
                        <h1 class="title is-4">您好,我是 SevDot。</h1>
                        <p class="subtitle is-6">我是一名软件开发者和终身学习者,偶尔也写博客文章。</p>
                        <hr>
                        <div class="content">
                            <h2>关于博客</h2>
                            <p>基于 Laravel 和 Bulma 开发的个人博客应用。</p>
                            <hr>
                            <h2>公众号</h2>
                            <hr>
                            <p>
                                <figure class="p-1">
                                    <img src="{{asset('images/sevdots.png')}}" alt="">
                                </figure>
                            </p>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
@stop

图片资源

在上面的页面中添加了图片,需要在 public目录下创建一个 images目录用于存放项目中的图片。

页面效果

  1. 首页

image.png

  1. 联系

image.png

  1. 关于

image.png