版面參考
今天就來處理大頭照下面的 skill 和 contact 區域吧~,可以發現兩個區域其實有滿多 svg icon 的,
而 Opshell 最喜歡使用 sprite 的方式處理 svg ,好處是程式碼很乾淨整齊,找東西和維護很方便:
小知識
所謂的 svg sprite 其實就像比較早以前的 image sprite 是一樣的邏輯,都是把很多張圖拼起來,然後透過 定位來顯示要用的圖片。比較不同的事實踐的方式,svg sprite 是透過把每一個 icon 的"路徑"用<symbol>
標籤包起來並賦與他id
要使用時只要在 svg 的xlink:href
呼叫這個 id 就可以囉。
當然我們可以手動的把自己要得 svg 加進 sprite 包裡面,但是這樣每次新增修改都有夠麻煩,一個好的工程師必須要有的素養就是想辦法自動化 (偷懶,所以我們找 vite-plugin-svg-icons
幫我們把散落的svg 打包起來。
yarn add vite-plugin-svg-icons -D
到 config
中設定一下,設定他要打包哪邊的 svg,包起來的格式及怎麼加入 body 讓我們引用。
最後再把喜歡的 svg 檔案放進 docs/public/icons/
裡面。
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
export default defineConfig({
vite: {
plugins: [
createSvgIconsPlugin({
iconDirs: [path.resolve(__dirname, '../', 'public/icons')], // 指定存放 svg 原始檔案的目錄
symbolId: '[name]', // 指定symbolId格式 預設:'icon-[dir]-[name]
inject: 'body-last', // | 'body-first' sprite插入位置
customDomId: '__svg__icons__dom__' // 自訂 Dom ID
})
]
}
});
在 docs/.vitepress/theme/index.ts
中啟動他的功能。
// [-]Svg Icon引用
import 'virtual:svg-icons-register';
在 docs/components/el/
中新增 元件 svgIcon.vue
:
<script setup lang="ts">
defineProps({
name: { type: String, required: true, default: 'circle' }
});
</script>
<template>
<div class="icon">
<svg class="svg">
<use :xlink:href="`#${name}`" />
</svg>
</div>
</template>
<style lang="scss">
.icon {
position: relative;
@include setFlex();
@include setSize(32px, 32px);
padding: 2px;
fill: var(--vp-c-brand-1);
transition: 0.2s $cubic-FiSo;
.svg {
@include setFlex();
@include setSize(100%, 100%);
}
}
</style>
這樣就可以像這樣子的使用啦:
<OrgaSectionBlock title="Contact">
<ul class="contact-box">
<li v-for="contact in contactList" :key="`contact-${contact.text}`" class="contact">
<ElSvgIcon :name="contact.icon" />
<a :href="contact.href" target="_blank" rel="noopener noreferrer">{{ contact.text }}</a>
</li>
</ul>
</OrgaSectionBlock>
很多範例喜歡用 icon font 的方式來做小圖示,的確是簡單方便。
但是有一些缺點: