在 Quasar Framework 使用自己的 SVG Icon

使用 Quasar Framework 可以輕鬆地套用 Material Icon 或是 Font Awesome 等網站的 Icon,但是如果要使用自己製作的 SVG Icon,那就需要動點手腳才能完成哩,這篇文章會介紹兩種在 Quasar 使用自製 SVG Icon 的方法。

關於 SVG Icon

在開始之前,首先要介紹 SVG 的格式。
其實 SVG Icon 是由一個個 <path> 所組成的字串,而這些 <path> 的值其實可以取出來,再重新組合成一個完整的字串,最後這個字串所呈現的結果也會與原先的 SVG Icon 相同。

Svg icon format

圖片來源為 Quasar Framework 官方在 QIcon 的文檔裡面,對於 Svg icon format 的說明

官方寫法

Image icons

使用 Quasar 官方提供的 Image icons 方法,就可以在 QBtn 與 QIcon 上使用我們的 SVG Icon 了。
不過 Image icons 有個缺點就是無法更改顏色,像是我們常會針對 Hover 與 Active 等狀態,去定義不同的 Icon 顏色,然而使用 Image icons 這種方式的話,我們就無法更改顏色哩。

Image icons

如果使用這個方法,可以把 SVG Icons 放在 /src/statics 資料夾下,這樣在寫檔案路徑時比較方便

Inlined svg

Quasar 在 v1.7 版本之後,新增了叫做 Inlined svg 的使用方法。
我們可以直接在 <q-icon> 裡面把 SVG 的原始內容複製貼上,基本上格式就如下圖所示,可以放 <path> 以及其他 SVG 會出現的標籤,像是 <circle> 或是 <rect> 等標籤。

Inlined svg

不過在 <svg> 標籤裡面不能放 <style> 這個標籤,如果你的 SVG Icon 有使用 <style> 標籤定義樣式的話,要額外改寫到 <path> 上才行。
上圖第三行就是在 <path> 加上 fill="none" 來定義 Icon 的預設顏色,所以如果要預先填入白色的話,就是在後面寫 fill="#fff" 就可以哩。

基本上官方提供的這個 Inlined svg 是可以使用的,操作很簡單,基本的屬性也都能直接定義,不過有個缺點就是 Vue 元件會出現 SVG 的原始碼,有些圖片的 <path> 長度很長,甚至有很多個 <path>,這時候程式碼就會顯得比較雜亂。

改良寫法

方法一:使用 QIcon 搭配 v-html

這是基於 Quasar 官方寫法 (Inlined svg) 的延伸版本,會想到這個寫法,是因為 SVG Icon 的原始碼通常都很長一串,如果我們的專案有使用 ESLint 來規範程式碼,就會出現因為 <path> 字數太多而跳錯的問題。

要解決這個問題,我們可以將 SVG Icon 儲存成一個 JS 檔案,等到要使用的時候再透過 v-html 把這個檔案塞進 <q-icon> 裡面就可以了。

1
2
// src/path/to/exampleSvg.js
export default '<svg xmlns="..." viewBox="0 0 30 30"><circle cx="15" cy="15" r="15"/><path class="a" d="M21.113,22.9H11.506a1"/></svg>';

接下來我們還不能直接使用 v-html,在那之前我們需要先把 JS 檔案 import 進來,並且做一個初始化的動作,這樣後續使用時才能吃到內容。

1
2
3
4
5
6
7
8
import exampleSvg from '../path/to/exampleSvg.js';

export default {
name: 'exampleCard',
created() {
this.exampleSvg = exampleSvg;
},
};

都完成之後,就能使用 v-html 插入 Icon 囉!

1
<q-icon v-html="exampleSvg" size="30px" color="primary" />

重點補充說明:

  • 外框可再加上 v-ripple:white 來模擬 QBtn 的點擊效果
  • 可直接調整 size 與 color,不需要使用到 /deep/
  • QIcon 內部字體的顏色 (fill) 需使用 .deep-icon /deep/ .a 來指定調整

方法二:使用 QBtn 搭配 /deep/

上面的延伸寫法是 QIcon 使用的,但是 Quasar 裡面其實還有很多 Components 都會使用到 Icon,像是 QBtn 就是最常見的案例,因此方法二會介紹以常規方式使用 Quasar 元件時,該怎麼使用自己的 SVG Icon。

Step 1:將 SVG Icon 全部轉成字串

如何將 SVG Icon 轉為字串格式:

  • <path> 裡面 d="..." 的內容全部擷取出來,組合成一個新的字串
  • 如果 Icon 由多個 <path> 組成,可以用一個空格區分不同的 <path> 的內容
  • viewBox 加在字串的最後方,以一個 | 符號與前面的內容分隔開。

最後製作出來的結果就會是一個字串格式,我們將這個字串匯出,並儲存為一個 JS 檔案。

1
export default 'M20.142,.....,27.165Z|0 0 30 30';

Step 2:如何使用

接下來一樣要先做 import 與初始化(與方法一相同)的動作,才能在 <q-btn> 上使用剛才做好的字串 Icon。

我們可以透過 v-bind:icon 的方式把我們的 Icon 綁上去,並且使用 @click:color 的三元運算,來完成模擬 Qbtn 的點擊效果。
例如:

1
2
3
4
5
6
7
8
<q-btn
round
flat
:icon="exampleSvg"
@click="isThumbUp = !isThumbUp"
:color="isThumbUp? 'primary': 'grey'"
size="14px"
></q-btn>

重點補充說明:

  • 可使用 CSS /deep/ 來調整按鈕的字體大小 (.q-icon) 與寬高 (.q-btn__wrapper)
  • 透過 @click:color 切換按鈕顏色(三元條件運算子)

參考資料

  1. javascript - Icon in Quasar Button Component does not change size - Stack Overflow

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。