iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
自我挑戰組

不用前端框架 手把手打造基礎SPA網站系列 第 17

[DAY17]進階應用 - 幫你的SPA套上Bootstrap

  • 分享至 

  • xImage
  •  

前面我們以原生Javascript手動完成SPA的基礎架構,從建立Component,到設定Route與Router,並搭配Webpack進行模組化的開發。前面實做主要希望讓各位了解SPA的實踐精神與原理,為了增強日後的實用性,接著試試來做些進階延伸的應用,讓你的SPA生態變得更豐富。

今天延伸應用的主題是「幫你的SPA套上Bootstrap」,Bootstrap是一個CSS Framework,由Twitter團隊開發,之後作為開源專案釋出。看看維基百科的說明:

Bootstrap是一組用於網站和網路應用程式開發的開源前端(所謂「前端」,指的是展現給終端使用者的介面。與之對應的「後端」是在伺服器上面執行的代碼)框架,包括HTML、CSS及JavaScript的框架,提供字體排印、表單、按鈕、導航及其他各種元件及Javascript擴充套件,旨在使動態網頁和Web應用的開發更加容易。

先看一下完成會是什麼樣子:

安裝Bootstrap

Bootstrap官網參考安裝的步驟,首先我們透過NPM安裝Bootstrap:

$ npm install bootstrap

安裝完畢會在package.json的dependencies看到bootstrap與版本資訊,並且在node_modules裡多了bootstrap的資料夾。

將Bootstrap引入scss

之前我們有先安裝scss-loader,並搭配webpack將scss轉譯為css,這邊在src目錄裡建立一個scss的資料夾,專門放入相關scss檔,結構如下:

這邊說明一下各個scss檔:

  • _custom.scss:自訂class樣式
  • _variables.scss:scss變數設定
  • style.scss:scss的進入點

都建立好後在進入點裡直接引入:

src/scss/style.scss:

//引入scss變數
@import 'variables';
 
// 從node_modules裡引入
@import '~bootstrap/scss/bootstrap.scss';
 
// 引入google font
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
 
//引入自訂義樣式
@import 'custom';

為了讓字型有變化,這邊我們多引入了google font的Roboto字型。引入後在variables與custom裡做以下設定:

src/scss/_custom.scss:

body {
  font-family: 'Roboto', sans-serif;
}

src/scss/_variables.scss:

//改寫bootstrap變數設定
$primary: #00b1b1;

一切完成後,再次確認webpack.config.js裡有設定轉譯scss,以及是否將轉譯後的css做引入。

加入Navbar

到Bootstrap官網裡有個Navbar的元件,把html代碼複製起來,我們在src裡建立components資料夾,專門放入共用組件:

src/components/Navbar.js:

export const Navbar = `
    <nav class="navbar navbar-expand-md navbar-dark bg-primary">
        <a class="navbar-brand" href="#/">SPA with Router</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbar">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active">
                    <a class="nav-link" href="#/">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#/post">Post</a>
                </li>
                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" href="#" id="dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
                    <div class="dropdown-menu" aria-labelledby="dropdown">
                        <a class="dropdown-item" href="#">Profile</a>
                        <a class="dropdown-item" href="#">Logout</a>
                    </div>
                </li>
            </ul>
        </div>
    </nav>
`

這邊有兩種方式可以將Navbar整合至頁面裡:
1.在Home裡引入直接使用(較容易)
2.另外建立一個App.js做為最外層的外框容器組件,將Navbar.js引入這裡使用

第一個因為比較簡單,所以我們直接示範第二種,在src/pages裡建立App.js,並引入Navbar.js使用:

src/pages/App.js:

import { Navbar } from '../components/Navbar'

export const App = {
  render: (conponent) => {
    return `
        ${Navbar}
        <div class="py-5">${conponent}</div>
    `
  },
}

這裡注意的是,pages裡組件輸出為物件裡含有render屬性的格式,其中會把html部份放入render裡。

將Home套入外框組件中

這時多了App.js外框組件,並且Navbar.js在其中,那麼原先的Home.js要怎麼套入外框組件呢?其實只要把Home.js做點改變就好:

src/pages/Home.js:

import { App } from './App'
 
export const Home = {
  render: () => {
    const content = `
      <div class="container">
        <h1>Home page</h1>
        <div>Welcome to my page!</div>
      </div>
    `
    return App.render(content)
  },
}

最後return把home的content內容套入App的畫面裡,所以返回App.render(content)

成果一覽

可以看到頁面開始切換了,不過你知道的,當你點了後面的Dropdown時,像極了Bug:

「什麼?竟然沒有出來選單O_o??」

這是因為Bootstrap4裡其實有搭配Jquery與popper.js,所以我們要下載上述套件,透過NPM安裝:

$ npm install jquery popper.js

然後在原本JS進入點index.js裡引入jquery與bootstrap自家搭配的JS就可以了:

src/index.js

//引入Jquery
import 'jquery'
import 'bootstrap/dist/js/bootstrap.bundle'
 
//引入scss
import './scss/style.scss'
 
//Router
import { Router } from './routes/Router'
 
//監聽hash變化&加載完畢事件
window.addEventListener('hashchange', Router)
window.addEventListener('load', Router)

小結

今日完成了套入Bootstrap,幫網站添加了一些色彩樣式,明天會進入第二個進階的主題,怎麼在頁面渲染完成後產生作用,我們明天見!

參考資料:
Webpack 前端打包工具 - 客製化 Bootstrap 樣式並進行編譯


上一篇
[DAY16]手動打造SPA - 建立Router與Route(下篇)
下一篇
[DAY18]進階應用 - SPA簡易生命週期實現
系列文
不用前端框架 手把手打造基礎SPA網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言