一、开发目标
我们在前面章节中为应用构建了三个静态页面,但是目前这几个静态页面的样式看起来还是有些简陋。
本章节将针对前面创建的几个静态页面进行样式优化,并在本章节的最后面为接下来的用户注册功能准备好一个注册页面。
二、样式美化
现在,让我们来新建一个分支,接下来针对样式的调整修改都将在此分支上进行:
$ git checkout master $ git checkout -b filling-layout-style
1,Bootstrap
2,网站导航
使用 Bootstrap 来为网站添加顶部导航,加入一些基本的如 LOGO,帮助页,登录页等链接,方便用户跳转,随着后面功能的添加,该导航也会被不断完善。
Laravel 项目默认集成了 Bootstrap 前端框架,但还是需要你做一定配置之后才能够正常使用,在接下来的配置过程中,你将学到一些前端开发工作流相关的知识。
Laravel 项目默认集成了 Bootstrap 前端框架,但还是需要你做一定配置之后才能够正常使用,在接下来的配置过程中,你将学到一些前端开发工作流相关的知识。
Bootstrap 是以 NPM 扩展包的形式集成到 Laravel 项目中的,NPM 是 Node.js(一个基于 Google V8 引擎的 JavaScript 运行环境)的包管理和分发工具。Composer 的一些概念也是从 NPM 中借鉴过来的,因此 NPM 也有个类似 composer.json
文件的 package.json
文件,Laravel 默认会为每个新建的项目自动生成该文件,并会在文件里面默认集成一些较为常用的扩展包。我们可以在编辑器中查看此文件:
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.18", "bootstrap": "^4.0.0", "cross-env": "^5.1", "jquery": "^3.2", "laravel-mix": "^4.0.7", "lodash": "^4.17.5", "popper.js": "^1.12", "resolve-url-loader": "^2.3.1", "sass": "^1.15.2", "sass-loader": "^7.1.0", "vue": "^2.5.17" } }
Laravel 默认集成了一些 NPM 扩展包,我们重点看以下几个:
bootstrap —— Bootstrap NPM 扩展包;
jquery —— jQuery NPM 扩展包;
laravel-mix —— 由 Laravel 官方提供的静态资源管理工具;
vue —— VUE.js 前端框架;
这些扩展包,为 Laravel 提供了一套完整的前端工作流。
我们可以使用 NPM 对这些扩展包进行安装,但由于 NPM 的安装速度,安全性和稳定性等都饱受开发者的诟病,因此我们在教程中改用 Facebook 在 2016 年的 10 月份开源的 Yarn 来作为 NPM 的替代品,在后面的章节中我将为大家详细讲解 NPM 和 Yarn 之间的关系。现在先让我们使用 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 相关的知识进行补充讲解。
先打开package.json干掉你讨厌的cross-env ctrl+s保存,once again
将 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="{{ mix('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://laravel-china.org/courses/laravel-essential-training">Laravel 入门教程</a> 的示例项目主页。 </p> <p> 一切,将从这里开始。 </p> <p> <a class="btn btn-lg btn-success" href="#" role="button">现在注册</a> </p> </div> @stop
现在刷新页面会看到整个页面样式有点混乱,让我们来优化调整下吧。
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
文件夹里。
这时候我们刷新页面:
接着让我们将本次更改纳入版本控制中:
$ git add -A $ git commit -m "初始化样式"
三、Laravel前端工作流
接下来讲解 Laravel 是如何利用 Sass, NPM, Yarn, Laravel Mix 来构成一套完整的前端工作流。
1,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; } }
2,NPM, Yarn, Laravel Mix
(1)NPM
NPM 是 Node.js 的包管理和任务管理工具,其强大的功能也是 Node.js 能够如此成功的因素之一。在使用 NPM 安装第三方模块(也可理解为扩展包)时,你需要在 package.json
中对要安装的模块指定好名称和版本号。然后运行下面命令进行安装:
$ npm install
在开始安装之前,npm install
命令会先检查 node_modules
文件夹是否已存在要安装的模块,如果该模块已安装,则跳过,接着安装下一模块。安装完成后,所有的第三方模块都将被下载到 node_modules
文件夹中。你也可以使用下面命令来强制安装所有模块,不管该模块之前是否安装过:
$ npm install -f
由于国内的网络环境原因,我们在使用 NPM 安装第三方模块时会耗费较长时间,我们可通过淘宝提供的加速镜像来解决该问题。本教程提供的 Homestead 安装包里已经做了加速镜像的配置,其他渠道安装的 Homestead 可以使用以下命令做 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 的输出目录。
(4)开始使用 Mix
使用 Mix 很简单,首先你需要使用以下命令安装 npm 依赖:
$ yarn install
安装成功后,运行以下命令即可:
$ npm run watch-poll
watch-poll
会在你的终端里持续运行,监控 resources
文件夹下的资源文件是否有发生改变。在 watch-poll
命令运行的情况下,一旦资源文件发生变化,Webpack 会自动重新编译。
在后面的课程中,我们需要保证 npm run watch-poll
一直处在执行状态中。
四、浏览器缓存问题
1、问题描述
现代化的浏览器,会对静态文件进行缓存,静态文件在本课程的范畴内,指的是 .css
、.js
后缀的文件。这是一个浏览器的优化功能,极大地加快了网页的加载速度,但是在我们日常开发和维护中,有时候会造成混淆。
开发时,你明明修改了样式,但是刷新浏览器却看不见变化,然后你就来回不断地修改你的样式文件,做各种测试,浏览器页面仍然一成不变。直到你重新刷新好多次,或者修改样式文件名称时,才恍然大悟,原来是浏览器缓存了。
2、解决方案
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
文件里的逻辑遥相呼应。接下来刷新页面,查看页面源代码:
另外的,线上环境中,我们一般会使用 CDN 服务器来加载静态文件,以达到优化网页加载速度的效果。CDN 也会遇到像浏览器缓存类似的问题,Laravel Mix 的 version()
同时也是一个很好解决文件版本变更的方案。
接着让我们将本次更改纳入版本控制中:
$ git add . $ git commit -m "静态文件浏览器缓存问题"
五、局部视图
1,局部视图
介绍完前端工作流以后,我们接下来回到代码中。现在我们的应用已拥有顶部导航,但还存在一个问题。随着后面顶部导航功能愈加完善,代码量也会越来越多,如果把所有代码都放在默认视图文件中,会让这个文件变得无法维护,这明显不符合 Laravel 项目开发的最佳实践。因此我们需要把顶部导航从 default 视图中分离出来,成为一个单独的头部视图。
2,头部和底部
首先,我们需要新建一个头部视图文件。
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://iocaffcdn.phphub.org/uploads/sites/KDiyAbV0hj1ytHpRTOlVpucbLebonxeX.png"> <a href="https://laravel-china.org/courses" target=_blank> 刻意练习,每日精进 </a> <div class="float-right"> <a href="/about" >关于</a> </div> </footer>
3、样式优化
针对底部视图进行样式优化。
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; } small { float: left; } img.brand-icon { width: 17px; height: 17px; } }
4、引入局部视图
在完成头部视图和底部视图的定义后,接下来便可以在 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 提供的视图引用方法,可通过传参一个具体的文件路径名称来引用视图。
刷新页面:
接着让我们将本次更改纳入版本控制中:
$ git add . $ git commit -m "切割头部和尾部子视图"
六、布局中的链接
1、布局中的链接
由于我们进行了样式优化,现在的首页已经比一开始的好看多了。但视图里面的一些代码仍可以进行优化,比如链接地址。
<li><a href="/help">帮助</a></li>
上面的代码链接形式是 Web 开发中较为常用的一种,但在 Laravel 中,我们可以这么写:
<li><a href="{{ route('help') }}">帮助</a></li>
{{ }}
是在 HTML 中内嵌 PHP 的 Blade 语法标识符,表示包含在该区块内的代码都将使用 PHP 来编译运行。route()
方法由 Laravel 提供,通过传递一个具体的路由名称来生成完整的 URL。后面我们再来讲解路由名称的具体定义方法。
2、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/faq
,这时候,你只需要修改路由定义为以下即可:
Route::get('/faq', 'StaticPagesController@help')->name('help');
这样子不需要修改到其他代码。作为比较,如果不使用 route('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');
3、使用命名路由
由于我们都为路由指定好了名称,因此我们可以将头部视图和底部视图的链接更改为 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://iocaffcdn.phphub.org/uploads/sites/KDiyAbV0hj1ytHpRTOlVpucbLebonxeX.png"> <a href="https://laravel-china.org/courses" target=_blank> 刻意练习,每日精进 </a> <div class="float-right"> <a href="{{ route('about')}}" >关于</a> </div> </footer>
接着让我们将本次更改纳入版本控制中:
$ git add . $ git commit -m "命名路由"
七、用户注册页面
1、静态页面
在我们后面的教程中,将会为应用添加注册登录的功能,本节让我们先来完成用户注册功能的第一步:为用户注册功能创建基本的静态页面。
2、注册路由
按照我们之前的讲的构建流程,我们需要先为路由定义一个 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 框架兼容这两种写法。
3、生成用户控制器
现在我们还没有用户控制器,让我们运行下面命令来生成。
$ 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'); } }
4、注册页面视图
接下来让我们来添加一个简单的注册视图,后面再为该视图加上表单,让用户可以提交自己的个人信息。
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://laravel-china.org/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
页面呢?
接着让我们将本次更改纳入版本控制中:
$ git add . $ git commit -m "用户注册页面"
八、小结
1、提交代码
至此,我们已完成本章的项目开发,接下来让我们切回到 Git 的主分支上
$ git checkout master
这时我们运行 Git 的状态检查命令,会发现新增了一个 public/css
文件夹。这是为什么呢?
$ git status git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: public/css/app.css Untracked files: (use "git add <file>..." to include in what will be committed) public/mix-manifest.json no changes added to commit (use "git add" and/or "git commit -a")
原因是我们在前面使用了 npm run watch-poll
来监听文件的更改并持续编译,因此当我们切回到主分支上时,app.scss
文件会回到一开始在主分支上未经过任何修改的状态,这时 app.scss
文件被 watch-poll 任务检测到发生更改,便会对该文件进行编译,最终产生一个 public/css/app.css
文件。但这个文件对我们来说是个累赘,没有一点作用,原因如下:
新编译的 app.css
文件没有包含我们本章新添加的样式代码,因为它是由初始状态的 app.scss
文件编译成的。
在 Git 分支 filling-layout-style
上已新增了 app.css
,若将该分支与主分支进行合并,将导致文件冲突的情况发生。
解决冲突的方法很简单,先检出 Master,放弃所有文件修改,再进行分支合并即可。
$ git checkout . $ rm -f public/mix-manifest.json $ git merge filling-layout-style
最后让我们将代码推送到 GitHub 和 Heroku 上。
$ git push $ git push heroku master
Chrome 浏览器查看我们的 Heroku 应用:
经过本章节的学习,我们学到了以下内容:
Bootstrap 前端框架的基本介绍与使用;
Laravel Mix 前端工作流;
Sass 语法的基本使用;
局部视图的定义和引用;
命名路由的使用;