隨機手札 雜七雜八之地

部落格Nuxt 2升級Nuxt 3(一):bootstrapVue置換成自製的bootrap5元件

4 min前端筆記
#blog #nuxt #vue #nuxt2 #nuxt3 #bootstrapVue #bootstrap 4 #bootstrap 5 #bootstrap

之前規劃,部落格升級 Nuxt3 的第一步是先把 bootstrapVue 抽換成自己實做的 bootstrap5。這篇是紀錄過程中覺得特別困難或是需要研究的部份。


元件中比較麻煩的是 Modal,原生的 Bootstrap 的 Modal 會在body加上一個div.modal-backdrop元素作為底層,原本的.modal元素則保留在原本的位置,如果遇到上層元素有position: sticky;或是position: absolute等等會用到z-index的 css 屬性,會導致.modal元素因為跟著上層元素的z-index計算而被div.modal-backdrop遮住。

例如:

<header class="position-stickty" style="z-index: 10;">
  <div class="modal"></div>
</header>

原本 bootstrapVue 的作法,是把.modal-backdrop元素連同.modal元素一起加到body裡面,使其脫離可能受影響的父層,猜想這邊應該是使用$mount去做處理。但因為部落格用到的 modal 元件很少而且全部都在 header 裡面(基本上等於全域),所以就乾脆移轉到layouts/default.vue元件裡了,開關則從 store 做處理。

畢竟之後還會再更換 UI 框架,這邊就簡單處理,升上 Nuxt 3 之後再直接使用<Teleport>元件。


Directives

第二麻煩的則是 directives,部落格用到的 bootstrapVue directives 有兩個:VisibleScollspy

Visible

因為之前已經有使用 IntersectionObserver 實做延遲載入的經驗,自己覺得 Visible 不算太難。自己寫起來大概長這樣:

bVisible.js
let intersectionObserver = null

export default {
  inserted(el, { value }) {
    if (typeof value === 'function') {
      intersectionObserver = new IntersectionObserver((entries) => {
        value(entries[0].intersectionRatio > 0)
      })

      intersectionObserver.observe(el)
    }
  },
  unbind() {
    if (
      intersectionObserver &&
      intersectionObserver instanceof IntersectionObserver
    ) {
      intersectionObserver.disconnect()
    }
  },
}

Scrollspy

Scrollspy 是 bootstrap 原生內建的功能,主要目的是用來偵測滾動的元素 ID 若與在.nav .nav-item .nav-link裡面hrefhash相符的話,就給予active的 class。

自己寫出來大概長這樣:

bScrollspy.js
let Scrollspy = null
let scrollSpy = null

export default {
  inserted(target) {
    if (process.client) {
      if (!Scrollspy) Scrollspy = require('bootstrap/js/dist/scrollspy')
      scrollSpy = new Scrollspy(document.body, { target })
    }
  },
  unbind() {
    scrollSpy.dispose()
  },
  componentUpdated() {
    scrollSpy.refresh()
  },
}

因為 Scrollspy 包含 client 端的程式碼操作,要判斷process.client才初始化,否則使用npm run dev或是npm run generate時會有錯誤。


暗黑模式

最後是暗黑模式,bootstrap5 內建暗黑模式,使用方式也滿簡單的,就是直接在html標籤上加上data-bs-theme="dark"

<html data-bs-theme="dark"></html>

基本的元件若沒有用text-white或是bg-white之類的樣式覆寫,就會自動根據暗黑模式而更改了,若有需要特別區分出像這個部落格一樣的前景、背景色之類的,可以參考node_modules/bootstrap/scss/variables-dark"檔案,去使用已經內建的一些變數來簡單做出暗黑模式。


後記

在部落格升級的過程中,自己覺得比較困難或要特別注意的就是上述這幾個了。其他像原本代表左右的lr要換成startend、圓角使用的rounded大小不再是使用sm/lg這種而是轉用數字……之類的小事,直接看官方的升級指引就 OK。


Support me on Ko-fi