页面布局(下):引入 Tailwind CSS 框架构建博客应用 UI 界面


上篇教程中,学院君给大家演示了单页面博客应用前端路由和页面布局的基本构建,不过由于没有应用任何 CSS 样式代码,所以 UI 界面很丑陋,今天,学院君将引入 Tailwind CSS 框架来美化这个博客应用的 UI 界面。

基于 Laravel Mix 引入 Tailwind

在 Laravel 项目中,我们可以基于 Lavavel Mix 快速引入 Tailwind CSS 框架,开始之前,先安装 laravel-mix-tailwind 这个前端依赖包:

npm install laravel-mix-tailwind --save-dev

安装完成后,需要在项目根目录下的 webpack.mix.js 中引入它:

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

require('laravel-mix-tailwind');

...

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

由于 laravel-mix-tailwind 依赖 tailwind.js,所以还需要通过如下命令初始化 Tailwind:

npx tailwindcss init

如果上述命令运行报错,提示 Connot find module 'autoprefixer'

-w756

可以通过升级 npm 版本(以 Mac 为例)来解决:

brew upgrade npm

再继续运行初始化命令,就可以执行成功了:

-w728

接下来,我们将 tailwind.config.js 重命名为 tailwind.js

mv tailwind.config.js tailwind.js

然后在 resources/sass/app.scss 中移除 Bootstrap,引入 Tailwind:

...

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

// Tailwind
@import "~tailwindcss/base";
@import "~tailwindcss/components";
@import "~tailwindcss/utilities";

最后运行如下命令重新编译前端资源:

npm run watch

编译成功,则表明 Tailwind CSS 框架已正常引入。

安装 Tailwind 语法提示插件

我们将 resources/views 目录下的 welcome.blade.php 重命名为 app.blade.php,并在 routes/web.php 中修改渲染该视图模板的路由定义如下:

...

Route::get('/{any?}', function () {
    return view('app');
});

另外,我们在 PhpStorm 插件市场中安装下面这个 Tailwind 语法智能提示插件,从而提高编写 Tailwind 样式代码的效率:

-w999

做好上述准备后,就可以基于 Tailwind CSS 框架重构博客应用前端页面样式代码了。

纯手工编写 Tailwind 样式代码

你可以在 resources/views/app.blade.php 中仿照上篇教程给出的 WordPress 博客主题模板手动编写和调试页面布局样式代码如下:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <link href="{{ asset('/css/app.css') }}" rel="stylesheet">
    </head>
    <body class="font-sans">
        <div id="app">
            <div class="container px-8">
                <main class="flex">
                    <!-- 侧边栏(导航菜单) -->
                    <aside class="w-1/5 pt-8">
                        <section class="mb-10">
                            <ul class="list-reset">
                                <h1 class="mb-4">
                                    <img src="/images/logo.png" alt="学院君博客"/>
                                </h1>
                                <li class="leading-loose">
                                    <router-link to="/">Home</router-link>
                                </li>
                                <li class="leading-loose">
                                    <router-link :to="{ name: 'category', params: { name: 'php' }}">PHP</router-link>
                                </li>
                                <li class="leading-loose">
                                    <router-link :to="{ name: 'category', params: { name: 'golang' }}">Golang</router-link>
                                </li>
                                <li class="leading-loose">
                                    <router-link :to="{ name: 'category', params: { name: 'javascript' }}">Javascript</router-link>
                                </li>
                                <li class="leading-loose">
                                    <router-link to="/about">About</router-link>
                                </li>
                                <li class="leading-loose">
                                    <router-link to="/feedback">Feedback</router-link>
                                </li>
                            </ul>
                        </section>
                    </aside>

                    <!-- 主体内容 -->
                    <div class="primary pt-12">
                        <!-- 路由匹配到的组件将渲染在这里 -->
                        <router-view></router-view>
                    </div>
                    
                    <!-- 底部内容 -->
                    <footer></footer>
                </main>
            </div>
        </div>

        <script src="{{ asset('/js/app.js') }}"></script>
    </body>
</html>

然后在浏览器中刷新应用首页,就可以看到如下布局视图了,左侧是菜单导航,右侧是主体内容:

-w1026

你如果喜欢自己倒腾和设计的话,可以结合 Chrome 开发者工具纯手工逐步调试和编写 Tailwind CSS 样式代码,不过如果你只是想快速完成功能,觉得这样效率比较低,也可以像 Bootstrap 那样去网上找开源代码,然后复制粘贴过来,按照自己的业务需求进行微调即可。

基于开源的 Tailwind 组件快速完成功能

学院君这里就是从网上拷贝过来的不同组件源码组合实现的博客页面布局样式。推荐一个不错的 Tailwind 组件素材库 —— Tailwind Components,在这里,你可以按需搜索自己想要的组件:

-w1349

相应的源代码都可以免费拷贝过来使用(不同于 Bootstrap,Tailwind 官方的 UI 库收费,所以这个网站是个非常好的 Tailwind UI 素材库替代方案)。

Tailwind 与 Bootstrap 相比另一个优势就是对于这些开源组件,不需要引入额外的 CSS 文件,只需要将 HTML 代码拷贝过来,就可以直接生效了。

下面贴出学院君基于 Tailwind CSS 实现的博客应用页面布局最终 UI 界面效果图:

-w1239

-w1217

-w1241

-w909

下面是相关的前端资源页面,主要调整的是视图模板 resources/views/app.blade.php,以及 resources/js/components 目录下的 Vue 单页面组件:

-w768

注意到我们这里新增了一个文章详情页命名路由:

{
    path: '/post/:id',
    name: 'post',
    component: require('./components/Post').default
},

其实现和上篇教程介绍的分类页面路由一样,不再多做介绍了。

关于上述页面布局和样式代码的实现,都已经提交这个 Github 代码仓库了:

https://github.com/nonfu/demo-spa.git

不再逐步演示贴出代码了,都是些非常简单的流程,如果你认真看过前面的 Vue 教程,很好理解。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 页面布局(上):基于 Vue Router 命名路由实现动态路由导航

>> 下一篇: Laravel 后端博客文章数据相关 API 接口提供