Bootstrap

在本书的教学过程中将使用 Bootstrap 来作为演示应用的前端框架。Bootstrap 是由 Twitter 的两位工程师 Mark Otto 和 Jacob Thornton 在 2011 年开源的一个 Web 前端框架。该框架兼容当下主流浏览器,并支持响应式设计,对新手友好,容易上手,且内置了非常多的样式组件可供使用。如果你对 Bootstrap 的使用不太熟悉,推荐你阅读下 Bootstrap 的 官方文档

网站导航

我们在很多网站上都能看到顶部导航的存在,因为这是个非常通用的产品需求,顶部导航能够让用户很方便的对网站进行浏览。接下来我们会使用 Bootstrap 来为网站添加顶部导航,加入一些基本的如 LOGO,帮助页,登录页等链接,方便用户跳转,随着后面功能的添加,该导航也会被不断完善。

Laravel 项目中使用 Bootstrap 前端框架,需要先执行以下命令:

  1. $ composer require laravel/ui:^1.0 --dev

composer require 是用来安装扩展包使用的命令,参数 --dev 是指定此扩展包只在开发环境中使用。

上面的命令安装完成后,使用以下命令来引入 Bootstrap :

  1. $ php artisan ui bootstrap

Bootstrap 是以 NPM 扩展包的形式集成到 Laravel 项目中的,NPM 是 Node.js(一个基于 Google V8 引擎的 JavaScript 运行环境)的包管理和分发工具。Composer 的一些概念也是从 NPM 中借鉴过来的,因此 NPM 也有个类似 composer.json 文件的 package.json 文件:

package.json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "axios": "^0.19",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.2",
        "laravel-mix": "^4.0.7",
        "lodash": "^4.17.13",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.15.2",
        "sass-loader": "^7.1.0",
        "vue-template-compiler": "^2.6.10"
    }
}

以上的 NPM 扩展包,我们重点看以下几个:

  • bootstrap —— Bootstrap NPM 扩展包;
  • jquery —— jQuery NPM 扩展包;
  • laravel-mix —— 由 Laravel 官方提供的静态资源管理工具。

这些扩展包,为 Laravel 提供了一套完整的前端工作流。

我们可以使用 NPM 对这些扩展包进行安装,但由于 NPM 的安装速度,安全性和稳定性等都饱受开发者的诟病。因此我们在教程中改用 Facebook 在 2016 年的 10 月份开源的 Yarn 来作为 NPM 的替代品,在后面的章节中我将为大家详细讲解 NPM 和 Yarn 之间的关系。

开始安装之前,我们需要设置安装器来使用国内的淘宝镜像加速,加速镜像的原理是使用国内的 CDN 来下载所需代码包,会更加顺畅:

$ npm config set registry=https://registry.npm.taobao.org
$ yarn config set registry 'https://registry.npm.taobao.org'

现在先让我们使用 Yarn 对扩展包进行安装,请在项目根目录下运行以下命令进行安装:

$ yarn install --no-bin-links
$ yarn add cross-env

在本教程提供的定制化 Homestead 安装包中,我们已默认为大家集成了 Yarn,因此不必再进行重复安装 Yarn,若你想了解具体的安装方式,可查阅 Yarn 官方安装文档

安装完成之后,让我们对 Laravel 默认生成的 app.scss 文件进行编辑,删除此文件里的所有内容,只留下面一行,导入 Bootstrap:

resources/sass/app.scss

// Bootstrap
@import '~bootstrap/scss/bootstrap';

细心的你可能会发现上面新建的样式文件后缀名(.scss)有别我们之前经常看到的样式文件后缀名(.css),这是因为 .scss 是 Sass(一种 CSS 开发工具)专属的文件格式,我们后面会再对 Sass 相关的知识进行补充讲解。

将 Bootstrap 导入成功之后,我们需要使用以下命令来将 .scss 文件编译为 .css 才能正常使用,编译命令如下:

$ npm run dev

我们也可以通过下面的命令,在每次检测到 .scss 文件发生更改时,自动将其编译为 .css 文件:

$ npm run watch-poll

请保证在进行项目开发时 npm run watch-poll 一直运行着,避免出现前端文件更改后没有应用到页面上的歧义。

执行成功可以看到以下:

所有编译后的资源文件都被存放在 public 文件夹中,你能在 public/css 文件夹中看到刚刚编译成功之后的文件。

接下来让我们更改基础视图的页面结构,为应用添加顶部导航,并加入帮助页和登录页的链接。

resources/views/layouts/default.blade.php

<!DOCTYPE html>
<html>
  <head>
    <title>@yield('title', 'Weibo App') - Laravel 入门教程</title>
    <link rel="stylesheet" href="/css/app.css">
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container">
        <a class="navbar-brand" href="/">Weibo App</a>
        <ul class="navbar-nav justify-content-end">
          <li class="nav-item"><a class="nav-link" href="/help">帮助</a></li>
          <li class="nav-item" ><a class="nav-link" href="#">登录</a></li>
        </ul>
      </div>
    </nav>

    <div class="container">
      @yield('content')
    </div>
  </body>
</html>

Laravel 在运行时,是以 public 文件夹为根目录的,因此我们可以使用下面这行代码来为 Laravel 引入样式:

<link rel="stylesheet" href="/css/app.css">

上面代码将引入 public/css/app.css 样式文件。

header, nav 是 HTML5 提供的一种语义化标签,其实际作用与 div 一致,语义化的标签能帮助机器更方便理解代码,使代码更简洁,有助于网站的 SEO 优化。我们在上面代码使用到一些如 navbar, container 等类名在 Bootstrap 中都拥有特殊含义。

现在让我们接着更改首页信息,加多一些页面元素。

resources/views/static_pages/home.blade.php

@extends('layouts.default')

@section('content')
  <div class="jumbotron">
    <h1>Hello Laravel</h1>
    <p class="lead">
      你现在所看到的是 <a href="https://learnku.com/courses/laravel-essential-training">Laravel 入门教程</a> 的示例项目主页。
    </p>
    <p>
      一切,将从这里开始。
    </p>
    <p>
      <a class="btn btn-lg btn-success" href="#" role="button">现在注册</a>
    </p>
  </div>
@stop

现在刷新页面会看到整个页面样式有点混乱:

优化页面 - 图1

接下来让我们来调整下:

resources/sass/app.scss


// Bootstrap
@import '~bootstrap/scss/bootstrap';

body {
    font-size: 14px;
    font-weight: normal;
}

nav.navbar.navbar-expand-lg {
    margin-bottom: 20px;
}

因为我们在上面运行着 npm run watch-poll 命令,watch-poll 任务会监控着 resources 下的文件变更。当你保存 app.scss 的动作被 watch-poll 命令捕捉到以后,就会触发自动编译功能,将 .scss 文件编译为 .css 文件,并存放到 public/css 文件夹里。

这时候我们刷新页面:

优化页面 - 图2

Laravel 前端工作流

接下来讲解 Laravel 是如何利用 Sass, NPM, Yarn, Laravel Mix 来构成一套完整的前端工作流。

SASS 语法基础

Sass 是一种可用于编写 CSS 的语言,起初由 Hampton Catlin 进行设计并由 Natalie Weizenbaum 开发。借助 Sass 我们可以少写很多 CSS 代码,并使样式代码的编写更加灵活多变。接下来我们将对 Sass 的几个主要功能进行讲解。

1. 样式文件导入

Sass 使用 @import 来导入其它的样式文件。如:

@import '~bootstrap/scss/bootstrap';

上面代码将导入 node_modules/bootstrap/scss/bootstrap.scss 文件。

你也可以使用下面代码来对单独一个文件进行导入:

@import "node_modules/bootstrap/scss/_alert.scss";

2. 变量

Sass 还允许你在代码中加入变量,所有的变量均以 $ 开头。

$navbar-color: #3c3e42;
.navbar-inverse {
  background-color: $navbar-color;
}

上面代码定义了一个 $navbar-color 颜色变量,在编译成功之后,变量将被替代为它所对应的值。

3. 嵌套

Sass 还允许你在选择器中进行相互嵌套,以减少代码量。

body div {
  color: red;
}

body h1 {
  margin-top: 10px;
}

可写成:

body {
  div {
    color: red;
  }

  h1 {
    margin-top: 10px;
  }
}

4. 引用父选择器

你还可以在 Sass 嵌套中使用 & 对父选择器进行引用:

a {
  color: white;
}

a:hover {
  color: blue;
}

可改写为:

a {
  color: white;
  &:hover {
    color: blue;
  }
}

NPM, Yarn, Laravel Mix

1. NPM

注意以下区块中 npm 安装相关的命令只用于说明,不需要在命令行中运行。我们将在本文后面使用 Yarn 来作为我们的安装器。

NPM 是 Node.js 的包管理和任务管理工具,其强大的功能也是 Node.js 能够如此成功的因素之一。在使用 NPM 安装第三方模块(也可理解为扩展包)时,你需要在 package.json 中对要安装的模块指定好名称和版本号。然后运行下面命令进行安装:

$ npm install

在开始安装之前,npm install 命令会先检查 node_modules 文件夹是否已存在要安装的模块,如果该模块已安装,则跳过,接着安装下一模块。安装完成后,所有的第三方模块都将被下载到 node_modules 文件夹中。你也可以使用下面命令来强制安装所有模块,不管该模块之前是否安装过:

$ npm install -f

由于国内的网络环境原因,我们在使用 NPM 安装第三方模块时会耗费较长时间,我们可通过淘宝提供的加速镜像来解决该问题。使用以下命令做 NPM 和 Yarn 安装加速:

$ npm config set registry=https://registry.npm.taobao.org
$ yarn config set registry 'https://registry.npm.taobao.org'

在本教程中,出于安装速度考虑,我们使用更加现代化的 Yarn 来替代 NPM 的包管理功能。然而我们仍然会使用到 NPM 的任务管理功能,如命令 npm run watch-poll

2. Yarn

Yarn 是 Facebook 在 2016 年 10 月开源的一个新的包管理器,用于替代现有的 NPM 客户端或者其他兼容 NPM 仓库的包管理工具。Yarn 在保留 NPM 原有工作流特性的基础上,使之变得更快、更安全、更可靠。在后面的项目开发中,我们统一使用 Yarn 来代替 NPM 进行安装包的管理。

我们可通过下面命令来安装当前项目的所有包:

$ yarn install

或是使用下面这种更加简洁的命令:

$ yarn

当执行 yarn install 命令时,Yarn 会先判断当前文件夹中是否存在 yarn.lock 文件,存在的话会按照文件中特定的包版本进行安装,否则读取 package.json 文件中的内容并发送到服务器上解析,解析成功后把结果写入 yarn.lock 文件中,最后安装扩展包。 Laravel 自带 yarn.lock 文件,此文件的作用与 composer.lock 一致,是为了保证项目依赖代码版本号绝对一致而存在的。

另外,我们也可以通过下面命令来添加指定的包:

$ yarn add [package]

3. Laravel Mix

Laravel Mix 一款前端任务自动化管理工具,使用了工作流的模式对制定好的任务依次执行。Mix 提供了简洁流畅的 API,让你能够为你的 Laravel 应用定义 Webpack 编译任务。Mix 支持许多常见的 CSS 与 JavaScript 预处理器,通过简单的调用,你可以轻松地管理前端资源。我们可以在 webpack.mix.js 文件中制定一些如资源文件的编译、压缩等任务。Laravel 已默认为我们生成了 webpack.mix.js 文件,并集成了 laravel-mix 模块。

webpack.mix.js

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

代码分解:

const mix = require('laravel-mix');

webpack.mix.js 的解析引擎是 Node.js ,在 Node.js 中require 关键词是对模块进行引用。

Mix 提供了一些函数来帮助你使用 JavaScript 文件,像是编译 ECMAScript 2015、模块编译、压缩、及简单的合并纯 JavaScript 文件。更棒的是,这些都不需要自定义的配置。

mix.js('resources/js/app.js', 'public/js')

以上这一行简单的代码,支持:

  • ECMAScript 2015 语法;
  • Modules;
  • 编译 .vue 文件;
  • 针对生产环境压缩代码。

js 方法的第二个参数可以用来自定义生成的 JS 文件的输出目录。

mix.sass('resources/sass/app.scss', 'public/css');

sass 方法可以让你将 Sass 文件编译为 CSS,你可以使用第二个参数来自定义生成的 CSS 的输出目录。

开始使用 Mix

使用 Mix 很简单,首先你需要使用以下命令安装 npm 依赖:

$ yarn install

安装成功后,运行以下命令即可:

$ npm run watch-poll

watch-poll 会在你的终端里持续运行,监控 resources 文件夹下的资源文件是否有发生改变。在 watch-poll 命令运行的情况下,一旦资源文件发生变化,Webpack 会自动重新编译。

在后面的课程中,我们需要保证 npm run watch-poll 一直处在执行状态中。

浏览器缓存问题

现代化的浏览器,会对静态文件进行缓存,静态文件在本课程的范畴内,指的是 .css.js 后缀的文件。这是一个浏览器的优化功能,极大地加快了网页的加载速度,但是在我们日常开发和维护中,有时候会造成混淆。

开发时,你明明修改了样式,但是刷新浏览器却看不见变化,然后你就来回不断地修改你的样式文件,做各种测试,浏览器页面仍然一成不变。直到你重新刷新好多次,或者修改样式文件名称时,才恍然大悟,原来是浏览器缓存了。

解决方案

Laravel Mix 给出的方案是为每一次的文件修改做哈希处理。只要文件修改,哈希值就会变,提醒客户端需要重新加载文件,很巧妙地解决了我们的问题。我们只需要对 webpack.mix.js 稍作修改,即可使用此功能:

webpack.mix.js

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css').version();

以上可看出,我们只是增加了 version() 函数的调用,其他未做修改。接下来还需要修改模板,使其动态加载样式代码:

resources/views/layouts/default.blade.php

<!DOCTYPE html>
<html>
  <head>
    <title>@yield('title', 'Weibo App') - Laravel 入门教程</title>
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container">
        <a class="navbar-brand" href="/">Weibo App</a>
        <ul class="navbar-nav justify-content-end">
          <li class="nav-item"><a class="nav-link" href="/help">帮助</a></li>
          <li class="nav-item" ><a class="nav-link" href="#">登录</a></li>
        </ul>
      </div>
    </nav>

    <div class="container">
      @yield('content')
    </div>
  </body>
</html>

以上代码只是做了这一行的修改:

<link rel="stylesheet" href="{{ mix('css/app.css') }}">

mix() 方法与 webpack.mix.js 文件里的逻辑遥相呼应。

注意:webpack.mix.js 文件只在 npm run watch-poll 指令执行时引入,之后指令后台运行不再重新引入。如果你后台运行 watch-poll 命令的话,需关闭 watch-poll 服务Ctrl + Z),再次启动( npm run watch-poll )即可生效。

接下来刷新页面,查看页面源代码:

优化页面 - 图3

另外的,线上环境中,我们一般会使用 CDN 服务器来加载静态文件,以达到优化网页加载速度的效果。CDN 也会遇到像浏览器缓存类似的问题,Laravel Mix 的 version() 同时也是一个很好解决文件版本变更的方案。

局部视图

介绍完前端工作流以后,我们接下来回到代码中。现在我们的应用已拥有顶部导航,但还存在一个问题。随着后面顶部导航功能愈加完善,代码量也会越来越多,如果把所有代码都放在默认视图文件中,会让这个文件变得无法维护,这明显不符合 Laravel 项目开发的最佳实践。因此我们需要把顶部导航从 default 视图中分离出来,成为一个单独的头部视图。

头部和底部视图

首先,我们需要新建一个头部视图文件。

resources/views/layouts/_header.blade.php

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container ">
    <a class="navbar-brand" href="/">Weibo App</a>
    <ul class="navbar-nav justify-content-end">
      <li class="nav-item"><a class="nav-link" href="/help">帮助</a></li>
      <li class="nav-item" ><a class="nav-link" href="#">登录</a></li>
    </ul>
  </div>
</nav>

可以看到,我们在头部视图的文件名前面加了下划线 _,这样做是为了指定该视图文件为局部视图,为局部视图增加前缀下划线是『约定俗成』的做法,方便了其它人快速地理解该文件的实际作用。从这里开始,我们都会为局部文件添加下划线前缀。

现在让我们再来为应用创建一个底部视图,用于置放网站的一些基础信息。

resources/views/layouts/_footer.blade.php

<footer class="footer">
  <img class="brand-icon" src="https://cdn.learnku.com/uploads/sites/KDiyAbV0hj1ytHpRTOlVpucbLebonxeX.png">
  <a href="https://learnku.com/laravel/courses" target=_blank>
    刻意练习,每日精进
  </a>

  <div class="float-right">
    <a href="/about" >关于</a>
  </div>
</footer>

样式优化

针对底部视图进行样式优化。

resources/sass/app.scss

.
.
.
/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #777;
  font-size: 13px;
  font-weight: bold;

  a {
    color: #555;
  }

  a:hover {
    color: #222;
  }

  img.brand-icon {
    width: 17px;
    height: 17px;
  }
}

引入局部视图

在完成头部视图和底部视图的定义后,接下来便可以在 default 视图中引用这两个视图。

resources/views/layouts/default.blade.php

<!DOCTYPE html>
<html>
  <head>
    <title>@yield('title', 'Weibo App') - Laravel 入门教程</title>
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
  </head>

  <body>
    @include('layouts._header')

    <div class="container">
      <div class="offset-md-1 col-md-10">
        @yield('content')
        @include('layouts._footer')
      </div>
    </div>
  </body>
</html>

@include 是 Blade 提供的视图引用方法,可通过传参一个具体的文件路径名称来引用视图。

刷新页面:
优化页面 - 图4

布局中的链接

由于我们进行了样式优化,现在的首页已经比一开始的好看多了。但视图里面的一些代码仍可以进行优化,比如链接地址。

resources/views/layouts/_header.blade.php

<li><a href="/help">帮助</a></li>

上面的代码链接形式是 Web 开发中较为常用的一种,但在 Laravel 中,我们可以这么写:

<li><a href="{{ route('help') }}">帮助</a></li>

{{ }} 是在 HTML 中内嵌 PHP 的 Blade 语法标识符,表示包含在该区块内的代码都将使用 PHP 来编译运行。route() 方法由 Laravel 提供,通过传递一个具体的路由名称来生成完整的 URL。后面我们再来讲解路由名称的具体定义方法。

Laravel 路由

我们在前面讲到,如果要使用下面这种方式来渲染 help 链接,则需要先为路由定义 help 路由名称。

<li><a href="{{ route('help') }}">帮助</a></li>

在 Laravel 中,我们可以通过在路由后面链式调用 name 方法来为路由指定名称:

Route::get('/help', 'StaticPagesController@help')->name('help');

当我们在页面渲染该路由时,route('help') 最终的渲染结果将如下:

http://weibo.test/help

可以看到 route('help') 为我们生成了完整的 URL 地址,这样当我们需要对生成的 URL 进行更改时,我们只需要改动路由文件即可,由此可见在实际开发中养成对路由的命名是一个好习惯,可以帮助我们节省很多工作量,另外也是 Laravel 项目开发的最佳实践。

这里举一个例子来说明:假如我们的应用中有 10 个地方使用 route('help') 方式书写这个 URL 地址,因为特殊原因,需要将 [http://weibo.test/help](http://weibo.test/help) 修改为 [http://weibo.test/faq](http://weibo.test/faq) ,这时候,你只需要修改路由定义为以下即可:

Route::get('/faq', 'StaticPagesController@help')->name('help');

这样子不需要修改到其他代码。作为比较,如果不使用 route('help') 方式,而是直接在代码中写入 [http://weibo.test/help](http://weibo.test/help) ,那你只能一个个的去手工修改。

了解了使用命名路由的好处之后,让我们开始动手,命名之前创建的几个路由。

routes/web.php

<?php

Route::get('/', 'StaticPagesController@home')->name('home');
Route::get('/help', 'StaticPagesController@help')->name('help');
Route::get('/about', 'StaticPagesController@about')->name('about');

使用命名路由

由于我们都为路由指定好了名称,因此我们可以将头部视图和底部视图的链接更改为 route() 的方式来生成。

resources/views/layouts/_header.blade.php

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container ">
    <a class="navbar-brand" href="{{ route('home') }}">Weibo App</a>
    <ul class="navbar-nav justify-content-end">
      <li class="nav-item"><a class="nav-link" href="{{ route('help') }}">帮助</a></li>
      <li class="nav-item" ><a class="nav-link" href="#">登录</a></li>
    </ul>
  </div>
</nav>

resources/views/layouts/_footer.blade.php

<footer class="footer">
  <img class="brand-icon" src="https://cdn.learnku.com/uploads/sites/KDiyAbV0hj1ytHpRTOlVpucbLebonxeX.png">
  <a href="https://learnku.com/laravel/courses" target=_blank>
    刻意练习,每日精进
  </a>

  <div class="float-right">
    <a href="{{ route('about') }}" >关于</a>
  </div>
</footer>

此时如果你 使用 Chrome 开发者工具 查看页面源代码,可以看到:

优化页面 - 图5

静态页面

在我们后面的教程中,将会为应用添加注册/登录的功能,本节让我们先来完成用户注册功能的第一步:为用户注册功能创建基本的静态页面。

注册路由

按照我们之前讲的构建流程,我们需要先为注册定义一个 signup 路由,当用户访问 http://weibo.test/signup 时将进入我们的注册页面。

routes/web.php

<?php

Route::get('/', 'StaticPagesController@home')->name('home');
Route::get('/help', 'StaticPagesController@help')->name('help');
Route::get('/about', 'StaticPagesController@about')->name('about');

Route::get('signup', 'UsersController@create')->name('signup');

这次我们把 signup 的路由请求交给用户控制器 UsersController 来处理。因为我们在后面会为注册页面添加上表单注册功能,到时候表单提交请求会与数据库进行交互,因此该页面并不能算静态页面,也就意味着我们不能再使用 StaticPagesController 来处理此动作。由于后面的用户注册、更新、删除等一系列操作都是围绕着用户进行的,因此统一使用用户控制器来处理此逻辑比较符合 Laravel 的开发规范。

注册路由时,URI signup/signup 从使用上来看,并无区别,Laravel 框架兼容这两种写法。

生成用户控制器

现在我们还没有用户控制器,让我们运行下面命令来生成。

$ php artisan make:controller UsersController

以上命令会生成 app/Http/Controllers/UsersController.php 文件。

在路由中,我们会将用户注册页面的请求指定给用户控制器的 create 方法进行处理,接下来让我们完成该方法的定义。

app/Http/Controllers/UsersController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UsersController extends Controller
{
    public function create()
    {
        return view('users.create');
    }
}

注册页面视图

接下来让我们来添加一个简单的注册视图,后面再为该视图加上表单,让用户可以提交自己的个人信息。

resources/views/users/create.blade.php

@extends('layouts.default')
@section('title', '注册')

@section('content')
<h1>注册</h1>
@stop

最后让我们修改首页注册按钮的链接,提供给用户一个进入注册页面的入口。

resources/views/static_pages/home.blade.php

@extends('layouts.default')

@section('content')
  <div class="jumbotron">
    <h1>Hello Laravel</h1>
    <p class="lead">
      你现在所看到的是 <a href="https://learnku.com/courses/laravel-essential-training">Laravel 入门教程</a> 的示例项目主页。
    </p>
    <p>
      一切,将从这里开始。
    </p>
    <p>
      <a class="btn btn-lg btn-success" href="{{ route('signup') }}" role="button">现在注册</a>
    </p>
  </div>
@stop

保存后刷新首页看看吧。试试看点击 现在注册 按钮是否会跳转到 signup 页面呢?

优化页面 - 图6