【Nova UI】十、打造組件庫第一個組件-圖標組件(下):從.svg 到 SVG Vue 組件的高效蛻變?

序言

在組件庫開發的精彩旅程中🚀,我們已經成功打造并完善了圖標組件體系,賦予其強大的功能和豐富的表現力🎉。然而,隨著業務版圖的不斷擴張🌐,手動逐個編寫 SVG Vue 組件的傳統方式,逐漸暴露出效率低下的短板。這種重復性的工作不僅耗費大量寶貴的時間?與精力💪,還容易在機械的操作中引入人為錯誤🚫。今天,讓我們一同踏上探索自動化生成的奇妙之路🧭,聚焦于如何借助神奇的代碼力量,通過.svg 文件自動生成 SVG Vue 組件,開啟簡化操作的嶄新時代🌟。這一轉變將如同為組件庫開發裝上了渦輪增壓引擎,推動開發效率實現質的飛躍,讓我們的開發工作更加高效、流暢 。

思路

為深入理解自動生成的實現邏輯,我們從阿里圖庫下載了一個典型的.svg 文件。其內部結構如下:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#2c2c2c" d="M474 152m8 0l60 0q8 0 8 8l0 704q0 8-8 8l-60 0q-8 0-8-8l0-704q0-8 8-8Z"  /><path fill="#2c2c2c" d="M168 474m8 0l672 0q8 0 8 8l0 60q0 8-8 8l-672 0q-8 0-8-8l0-60q0-8 8-8Z"  />
</svg>

剖析這個文件可知,我們所需的關鍵信息集中在<svg>節點及其子節點內容。為達成從.svg 文件到 SVG Vue 組件的轉換,首要任務是讀取該文件📄,精準提取所需數據📊,巧妙移除<svg>節點的非必要屬性,最終依據處理后的數據生成對應的 Vue 文件📝。

讀取 .svg 文件

const readFile = () => {const result = {}const files = fs.readdirSync(assetsRoot)files.forEach(file => {const path = `${assetsRoot}/${file}`let content = fs.readFileSync(path, 'utf8')content = format(content)const name = file.replace('.svg', '')result[name] = content})return result
}

此函數猶在指定目錄assetsRoot中,讀取所有.svg 文件。對每個文件,它打開并讀取內容,進行格式化處理,然后提取文件名(去除.svg 后綴)作為鍵,將處理后的內容作為值,存入結果對象。

提取 svg 標簽

function extractSvg(content) {const startIndex = content.indexOf('<svg')const endIndex = content.lastIndexOf('</svg>') + '</svg>'.lengthreturn content.slice(startIndex, endIndex)
}

該函數在整個文件內容中定位<svg>標簽的起始和結束位置,然后將這部分內容完整地裁剪出來。這一步確保我們只保留了與 SVG 圖形直接相關的部分,為后續的處理提供了純凈的數據基礎 。

移除svg標簽非必要屬性

function removeAttribute(content) {const removeAttrs = ['id', 'pid', 'class', 'width', 'height', 'version', 'fill']removeAttrs.forEach(attr => {const reg = new RegExp(` ${attr}="[^"]*"`, "g")content = content.replace(reg, '')})content = content.replace('<svg', '<svg fill="currentColor"')return content
}

這部分代碼專門清理<svg>標簽中那些我們不需要的屬性。通過正則表達式,它逐個匹配并移除諸如idpidclass等非必要屬性。同時,為了確保圖標顏色能根據上下文靈活變化,它將<svg>標簽的fill屬性替換為fill="currentColor"。經過這一番清理和設置,<svg>標簽變得簡潔且符合我們的需求 。

將 提取的 svg 內容 轉為 vue 內容

function toComponentContent(name, content) {const result = `
<template>${content}
</template><script setup>defineOptions({name: 'N${name}Svg',})
</script>
`return result
}

這個函數將提取并處理好的 SVG 內容,巧妙地包裝成 Vue 組件的形式。它創建了一個包含<template><script setup>的 Vue 組件模板,將 SVG 內容放入<template>中,并在<script setup>中定義了組件的名稱。經過這一步,原本的 SVG 數據搖身一變,成為了可以在 Vue 項目中直接使用的組件 。

駝峰轉換

function toGreatHump(value) {return value.split('-').map(item => item.replace(item.charAt(0), item.charAt(0).toUpperCase())).join('')
}

該函數對字符串進行駝峰命名法的轉換。它將以-分隔的字符串,轉換為每個單詞首字母大寫的駝峰形式。例如,icon-close會被轉換為IconClose。這種轉換使得組件名稱在符合 Vue 命名規范的同時,也更具可讀性和一致性 。

寫入vue文件

function writeComponentFile(key, content) {const greatHumpName = toGreatHump(key)const data = toComponentContent(greatHumpName, content)const path = `${componentsRoot}/${key}.vue`fs.writeFile(path, data, error => error && console.error(error))
}

這部分代碼將轉換好的 Vue 組件內容寫入到指定路徑的.vue 文件中。它先將文件名轉換為駝峰形式,然后結合之前生成的 Vue 組件內容,將數據寫入到componentsRoot目錄下對應的.vue 文件。如果在寫入過程中出現錯誤,它會在控制臺輸出錯誤信息,方便我們及時排查和解決問題 。

轉成import、export語句

function toImport(keys) {return keys.map(key => `import ${toGreatHump(key)} from './components/${key}.vue'`).join('\n')
}
function toExport(keys) {return `export {${keys.map(key => toGreatHump(key)).join(',\n  ')}
}`
}

這兩個函數負責生成導入和導出語句。toImport函數遍歷所有的組件文件名,生成對應的import語句,這些語句將每個組件從其對應的.vue 文件中引入。toExport函數則將所有組件名以合適的格式組合成export語句,方便在其他地方統一引入這些組件。通過這兩個函數,我們構建了一個清晰的組件導入導出體系,使得組件在項目中的使用更加便捷 。

轉為 TS type語句

function toType(keys) {return `export const svgs = [\n${keys.map(key => `  '${toGreatHump(key)}'`).join(',\n')},\n] as const`
}

此函數將所有組件名整理成一個類型聲明語句。這個語句定義了一個包含所有組件名的常量數組svgs,并且使用as const確保其類型為只讀常量數組。在 TypeScript 項目中,這個聲明有助于在使用這些組件時進行類型檢查,提高代碼的安全性和穩定性 。

寫入主入口文件

function writeMainFile(keys) {const importData = toImport(keys)const exportData = toExport(keys)const typeData = toType(keys)const data = `${importData}\n\n${exportData}\n\n${typeData}\n`const path = `${mainRoot}/index.ts`fs.writeFile(path, data, error => error && console.error(error))
}

這個函數是整個自動化流程的 “收尾大師”🎨,它將前面生成的導入語句、導出語句和類型聲明語句整合在一起,寫入到主入口文件index.ts中。這個文件就像是組件庫的大門,所有外部對組件庫的訪問都通過這個文件進行。通過將這些關鍵信息寫入其中,我們完成了組件庫的整體搭建,使得所有組件能夠有序地被引入和使用 。

文件寫入

const writeFile = json => {for (const key in json) {if (Object.prototype.hasOwnProperty.call(json, key)) {writeComponentFile(key, json[key])}}const keys = Object.keys(json)writeMainFile(keys)
}

這個函數是整個自動化流程的 “指揮官”👨???,它統籌協調各個部分的工作。它遍歷包含所有 SVG 文件內容的對象,對每個文件內容調用writeComponentFile函數,將其寫入對應的.vue 文件。然后,收集所有的文件名,調用writeMainFile函數,將相關的導入、導出和類型聲明語句寫入主入口文件。通過這個函數的調度,整個自動化生成過程得以有條不紊地完成 。

運行

function run() {const json = readFile()writeFile(json)
}run()

只要運行這個run方法,就會在packages/svgs/components下生成對應的 Vue 文件,在packages/svgs/生成index.ts主入口文件。

你以為到這里就夠了嗎?還不行!每次運行的時候都要切換到packages/svgs目錄下,這顯然不是很便捷。所以,我們可以在根目錄下的package.json文件中scripts屬性下增加一行?"svg:build": "pnpm -C packages/svgs run init"?。這樣,每次只要在packages\svgs\assets目錄下放上.svg 文件,并在命令行運行npm run svg:build,就會自動生成所需的組件和主入口文件。是不是超級方便呢?這一優化讓我們的開發流程更加流暢,大大提高了工作效率,為組件庫的持續發展和完善提供了有力支持 。

🦀🦀感謝看官看到這里,如果覺得文章不錯的話🙌,點個關注不迷路?。
誠邀您加入我的微信技術交流群🎉,群里都是志同道合的開發者👨?💻,大家能一起交流分享摸魚🐟。期待與您在群里相見🚀,咱們攜手在開發路上共同進步? !
👉點我

感謝各位大俠一路相伴,實在感激! 不瞞您說,在下還有幾個開源項目 📦,它們就像精心培育的幼苗 🌱,急需您的澆灌。要是您瞧著還不錯,麻煩動動手指,給它們點亮幾顆 Star ?,您的支持就是它們成長的最大動力,在此謝過各位大俠啦!

  • Nova UI組件庫:https://github.com/gmingchen/nova-ui
  • 基于 Vue3 + Element-plus 管理后臺基礎功能框架
  • 預覽:https://admin.gumingchen.icu
    • Github:https://github.com/gmingchen/agile-admin
    • Gitee:https://gitee.com/shychen/agile-admin
    • 基礎版后端:https://github.com/gmingchen/java-spring-boot-admin
    • 文檔:http://admin.gumingchen.icu/doc/
  • 基于 Vue3 + Element-plus + websocket 即時聊天系統
    • 預覽:https://chatterbox.gumingchen.icu/
    • Github:https://github.com/gmingchen/chatterbox
    • Gitee:https://gitee.com/shychen/chatterbox
  • 基于 node 開發的后端服務:https://github.com/gmingchen/node-server

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77150.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77150.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77150.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Golang | 倒排索引

文章目錄 倒排索引的設計倒排索引v0版實現 倒排索引的設計 通用搜索引擎 v.s. 垂直搜索引擎&#xff1a; 通用搜索引擎&#xff1a;什么都可以搜索&#xff0c;更加智能化垂直搜索引擎&#xff1a;只能搜自家數據庫里面的內容&#xff0c;一般都帶著搜索條件&#xff0c;搜索一…

Windows 10 上運行 Ollama 時遇到 llama runner process has terminated: exit status 2

在 Windows 10 上運行 Ollama 時遇到 llama runner process has terminated: exit status 2 錯誤&#xff0c;可能是由多種原因引起的。以下是逐步解決方案&#xff1a; 1. 檢查 Ollama 服務狀態 按 Win R 輸入 services.msc&#xff0c;找到 Ollama 服務&#xff0c;確保其狀…

PCI 總線學習筆記(五)

PCI 總線學習系列&#xff0c;參考自 技術大牛博客&#xff1a; PCIe 掃盲系列博文連載目錄篇 書籍&#xff1a;王齊老師的《PCI Express 體系結構導讀》 下面的文章中加入了自己的一些理解和實際使用中遇到的一些場景&#xff0c;供日后查詢和回憶使用 PCI 總線定義了兩類配置…

Spring Cloud Alibaba VS Spring Cloud

??Spring Cloud Alibaba 與 Spring Cloud 組件對比? ??服務發現與注冊中心? 功能???Spring Cloud???Spring Cloud Alibaba?對比說明??核心組件?EurekaNacosNacos 支持動態配置管理、健康檢查更靈活&#xff0c;且提供 DNS 服務發現能力。????健康檢查??…

Java—— 常見API介紹 第五期

JDK8以后新增的時間相關類 Date類ZoneId&#xff1a;時區Instant&#xff1a;時間戳ZoneDateTime&#xff1a;帶時區的時間 日期格式化類 SimpleDateFormat DateTimeFormatter&#xff1a;用于時間的格式化和解析 日歷類 Calendar LocalDate&#xff1a;年、月、日LocalTime…

Java與Kotlin在Android開發中的全面對比分析

趨勢很重要 語言發展背景與現狀 Android操作系統自2008年正式發布以來&#xff0c;Java長期作為其主要的開發語言。這種選擇源于Java語言的跨平臺特性、成熟的生態系統以及廣泛開發者基礎。然而&#xff0c;隨著移動開發需求的快速演變&#xff0c;Java在Android開發中逐漸暴…

第一部分:git基本操作

目錄 1、git初識 1.1、存在的問題 1.2、版本控制器 1.3、git安裝 1.3.1、CentOS平臺 1.3.2、ubuntu平臺 2、git基本操作 2.1、創建倉庫 2.2、配置git 3、工作區、暫存區、版本庫 4、基本操作 4.1、場景一 4.2、場景二 4.3、修改文件 5、版本回退 6、撤銷修改 …

正則表達式與python使用

一、Python正則表達式基礎 1. 導入模塊 Python通過 re 模塊實現正則表達式功能&#xff0c;需先導入模塊&#xff1a; import re2. 核心語法 普通字符&#xff1a;直接匹配字面值&#xff08;如 a 匹配字符 a&#xff09;。元字符&#xff1a; \d&#xff1a;匹配數字&…

從FP32到BF16,再到混合精度的全景解析

筆者做過目標檢測模型、超分模型以及擴散生成模型。其中最常使用的是單精度FP32、半精度FP16、BF16。 雙精度"FP64"就不說了&#xff0c;不太會用到。 #1. 單精度、半精度和混合精度 單精度&#xff08;FP32&#xff09;、半精度&#xff08;FP16&#xff09;和混合…

Hot100方法及易錯點總結2

本文旨在記錄做hot100時遇到的問題及易錯點 五、234.回文鏈表141.環形鏈表 六、142. 環形鏈表II21.合并兩個有序鏈表2.兩數相加19.刪除鏈表的倒數第n個節點 七、24.兩兩交換鏈表中的節點25.K個一組翻轉鏈表(坑點很多&#xff0c;必須多做幾遍)138.隨機鏈表的復制148.排序鏈表 N…

不在同一個局域網的遠程桌面連接怎么設置?本地內網計算機讓其他網絡遠程訪問6種常用方法

遠程桌面是一種重要的技術&#xff0c;它允許用戶通過網絡遠程訪問和控制另一臺計算機的桌面界面。但是&#xff0c;當被控制端和控制端不在同一個局域網內時&#xff0c;就需要進行一些額外的配置。本文將詳細介紹在不同局域網下設置遠程桌面的步驟&#xff0c;以幫助讀者順利…

天機學堂day10作業,完善兌換優惠券功能

UserCouponServiceImpl /*** 兌換碼兌換優惠券* param code*/TransactionalOverridepublic void exchangeCoupon(String code) {//1、校驗code是否為空if (StringUtils.isBlank(code)) {throw new BadRequestException("非法參數&#xff01;");}//2、解析兌換碼&…

JAVA工程師面試題(七)

1、遞歸實現1,1,2,3,5,8,….第30個數是多少&#xff1f; public static int Foo(int i) { if (i < 0) return 0; else if(i > 0 && i < 2) return 1; else return Foo(i -1) Foo(i - 2); }…

Qt基礎009(HTTP編程和QJSON)

文章目錄 軟件開發網絡架構BS架構/CS架構 HTTP基本概念QT的HTTP編程JSON數據概述QT生成JSON數據QT解析JSON數據 軟件開發網絡架構 BS架構/CS架構 ? 在計算機網絡和軟件開發中&#xff0c;CS架構&#xff08;Client-Server Architecture&#xff0c;客戶端-服務器架構&#x…

高精度電流檢測革命:同軸分流器的創新應用與技術演進

一、精密測量原理與結構創新 基于電磁場分布重構技術的新型同軸分流器&#xff0c;突破了傳統電流測量的物理限制。該器件采用三維環形電阻矩陣結構&#xff0c;通過多層級導電環的精密排列&#xff0c;實現了電流路徑的渦流自補償。區別于常規分流器的平板式設計&#xff0c;其…

【使用層次序列構建二叉樹(數據結構C)】

使用層次序列構建二叉樹&#xff08;C語言實現&#xff09; 在數據結構學習過程中&#xff0c;二叉樹的構建方式通常有遞歸建樹&#xff08;前序/中序&#xff09;和層次建樹&#xff08;廣度優先&#xff09;兩種。本文將介紹一種基于輔助隊列實現的層次建樹方法&#xff0c;并…

設置Rocky Linux盒蓋不休眠的3個簡單步驟

在 Rocky linux&#xff08;和其他基于 RHEL 的發行版&#xff09;中&#xff0c;當你關閉筆記本電腦的蓋子時&#xff0c;默認行為通常是使系統休眠。如果你想更改這一行為&#xff0c;例如&#xff0c;使系統在關閉蓋子時只是鎖定&#xff0c;你可以按照以下步驟操作&#xf…

WPF的發展歷程

文章目錄 WPF的發展歷程引言起源與背景&#xff08;2001-2006&#xff09;從Avalon到WPF設計目標與創新理念 WPF核心技術特點與架構基礎架構與渲染模型關鍵技術特點MVVM架構模式 WPF在現代Windows開發中的地位與前景當前市場定位與其他微軟UI技術的關系未來發展前景 社區貢獻與…

【器件專題1——IGBT第1講】IGBT:電力電子領域的 “萬能開關”,如何撐起新能源時代?

一、IGBT 是什么&#xff1f;重新認識這個 “低調的電力心臟” 你可能沒聽過 IGBT&#xff0c;但一定用過它驅動的設備&#xff1a;家里的變頻空調、路上的電動汽車、屋頂的光伏逆變器&#xff0c;甚至高鐵和電網的核心部件里&#xff0c;都藏著這個 “電力電子開關的瑞士軍刀”…

新聞速遞丨Altair 與 Databricks 達成合作,加速數據驅動型創新

NEWS Altair 近日宣布與數據和人工智能公司 Databricks 達成戰略合作&#xff0c;通過新一代數據統一化、圖譜驅動智能和企業級人工智能&#xff08;AI&#xff09;技術賦能雙方客戶。 此次合作整合了兩大平臺的核心優勢&#xff0c;將 Altair RapidMiner 平臺的強大功能&…