本篇文章同步發表於 2023 iThome 鐵人賽:Nuxt.js 3.x 筆記-打造 SSR 專案
Bootstrap 版本:v5.3.1
Sass 版本:v1.63.6
在 Nuxt 專案中,我們可以自由選擇 CSS 預處理器、CSS 框架或是 UI Library 來定義樣式。在 CSS 框架百家爭鳴的時代,這幾年熱門的 Tailwind CSS、基於 Vue.js 開發的 Quasar、或是搭配 Vue3 開發的 Element Plus 都能快速上手,協助我們打造精美的網站。
由於工作上較常使用 Bootstrap 協作,本篇將以 Bootstrap 5 搭配 SCSS 進行說明。
廣告
Bootstrap 5 簡介
Bootstrap 有豐富的 Sass 變數、mixins、網格系統、元件、JS 插件,Bootstrap 5 與先前版本最大的不同,除了將 jQuery 從相依項目中移除,也新增 Utilities API(基於 Sass Maps 生成 Utilities Class),可以更簡易的管理或擴充樣式,不需手刻太多 CSS 即可完成多元、複雜的畫面。
套件安裝
npm install bootstrap npm install sass
|
使用 Bootstrap 樣式搭配自訂樣式
在 assets/
靜態資源目錄定義 SCSS,範例 assets/scss/app.scss
,需注意 Bootstrap 樣式與自訂樣式引入順序:
不建議直接引入整包 bootstrap components bootstrap/scss/bootstrap
,選擇需要的樣式引入即可,避免 CSS 檔案過大,造成系統負擔
@import "bootstrap/scss/functions";
@import "./color"; @import "./variables";
@import "bootstrap/scss/variables"; @import "bootstrap/scss/variables-dark"; @import 'bootstrap/scss/maps'; @import "bootstrap/scss/mixins"; @import "bootstrap/scss/root";
@import "~bootstrap/scss/utilities";
@import "./utilities";
@import "bootstrap/scss/reboot"; @import "bootstrap/scss/type"; @import "bootstrap/scss/containers"; @import "bootstrap/scss/grid"; @import "bootstrap/scss/tables"; @import "bootstrap/scss/forms"; @import "bootstrap/scss/buttons"; @import "bootstrap/scss/helpers";
@import "bootstrap/scss/utilities/api";
@import "./style";
|
自訂樣式檔案結構:
assets/ |—— scss/ |—— app.scss |—— _color.scss |—— _variables.scss |—— _style.scss
|
自訂、擴充、調整 utilities:
透過 map-merge
合併 bootstrap utilities,詳細定義方式參考 官方文件
$utilities: map-merge( $utilities, ( "cursor": ( property: cursor, class: cursor, responsive: true, values: auto pointer grab ) ) );
|
配置全域共用 CSS
接著在 nuxt.config
配置全域共用 CSS,接下來整個專案 HTML 都能使用編譯後的樣式
export default defineNuxtConfig({ css: [ '@/assets/scss/app.scss' ], postcss: { plugins: { autoprefixer: true } } })
|
Nuxt 專案已內建 postcss,加上 autoprefixer: true
會自動為屬性加上瀏覽器相容性前綴
範例定義以下樣式:
.container { display: flex; }
|
編譯後的 CSS:
.container { display: -webkit-box; display: -ms-flexbox; display: flex; }
|
定義全域共用 Sass / SCSS 變數(搭配 Vite)
如果想在 .vue 檔內的 <style>
直接使用 Sass / SCSS 變數,需搭配 preprocessorOptions
進行配置
export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { scss: { additionalData: ` @import "@/assets/scss/_color.scss"; @import "@/assets/scss/_variables.scss"; ` } } } } });
|
$primary: #49240F; $secondary: #E4A79D;
|
接著就可以在 SCF(單一元件檔)使用 SCSS 變數
<template> <div> <h1>Hello World</h1> </div> </template>
<style lang="scss" scoped> h1 { color: $primary; } </style>
|
加上 scoped
,將樣式作用域限制在元件內,避免造成全域污染,如果希望樣式可以渲染到子元件,透過 :deep()
定義如下
:deep(h3) { color: $primary; }
|
使用 Bootstrap Plugins
在 plugins/
目錄註冊 Bootstrap JavaScript Plugins
- 新增
plugins/bootstrap.client.js
注意:Nuxt 會自動引入(auto imports)plugins,bootstrap plugins 要限制在 client 端使用,否則會拋錯 document is not defined ,檔名需加上 .client
後綴
- 透過
Provide
定義全局變數,將需要的 Bootstrap Plugins 注入到 NuxtApp
import * as bootstrap from 'bootstrap'; const { Modal, Collapse } = bootstrap;
export default defineNuxtPlugin(_nuxtApp => { return { provide: { bootstrap: { modal: element => new Modal(element), collapse: element => new Collapse(element) } } }; });
|
- 使用 Modal Plugins
<template> <div> <div class="modal fade" tabindex="-1" ref="modalRef"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> ... </div> <div class="modal-body"> ... </div> <div class="modal-footer"> <button type="button" data-bs-dismiss="modal">close</button> </div> </div> </div> </div> <button type="button" class="btn btn-success" @click="showModal"> 點我看 Modal </button> </div> </template>
<script setup> const { $bootstrap } = useNuxtApp(); const modalRef = ref(null); let modal; const showModal = () => { modal.show(); };
onMounted(() => { modal = $bootstrap.modal(modalRef.value); });
onBeforeUnmount(() => { modal.dispose(); }); </script>
|
動態樣式
動態樣式定義方式同 Vue3,在 CSS 使用 v-bind function
<template> <div> <h1>hello</h1> <h2>world</h2> <button @click="theme.color = 'red'">change color</button> </div> </template>
<script setup> const theme = ref({ color: 'green' }); </script>
<style lang="scss" scoped> h1, h2 { color: v-bind('theme.color'); } </style>
|
參考資源:
https://nuxt.com/docs/getting-started/styling
https://vite.nuxtjs.org/misc/common-issues#styleresources
https://getbootstrap.com/
廣告
評論