如何使用 Pug 創建更好的 Angular 模板
已發表: 2022-03-10作為一名開發人員,我很欣賞 Angular 應用程序的結構以及 Angular CLI 提供的許多配置選項。 組件為構建視圖、促進代碼可重用性、插值、數據綁定和其他視圖業務邏輯提供了一種驚人的方法。
Angular CLI 支持多種內置 CSS 預處理器選項,用於組件樣式,如 Sass/SCSS、LESS 和 Stylus。 但是,當涉及到模板時,只有兩個選項可用:HTML 和 SVG。 儘管存在許多更有效的選擇,例如 Pug、Slim、HAML 等。
在本文中,我將介紹您(作為 Angular 開發人員)如何使用 Pug 更有效地編寫更好的模板。 您將學習如何在您的 Angular 應用程序中安裝 Pug,以及如何將使用 HTML 的現有應用程序轉換為使用 Pug。
管理圖像斷點
一個名為BreakPoint Observer的內置 Angular 功能為我們提供了一個強大的接口來處理響應式圖像。 閱讀更多關於允許我們在雲中提供、轉換和管理圖像的服務。 閱讀相關文章 →
Pug(以前稱為 Jade)是一個模板引擎。 這意味著它是一種從集成了一些指定數據的模板生成文檔的工具。 在這種情況下,Pug 用於編寫模板,這些模板被編譯為接收數據和呈現 HTML 文檔的函數。
除了提供更簡化的模板編寫方式之外,它還提供了許多有價值的功能,這些功能不僅限於模板編寫,例如促進代碼可重用性、啟用 JavaScript 代碼嵌入、提供迭代器、條件等的混合。
儘管 HTML 被許多人普遍使用並且在模板中工作得很好,但它不是 DRY 並且很難閱讀、編寫和維護,尤其是對於較大的組件模板。 這就是 Pug 的用武之地。使用 Pug,您的模板變得更易於編寫和閱讀,並且您可以擴展模板的功能作為額外的好處。 在本文的其餘部分,我將向您介紹如何在 Angular 組件模板中使用 Pug。
為什麼你應該使用哈巴狗
HTML 基本上是重複的。 對於大多數元素,您必須有一個非 DRY 的開始和結束標籤。 您不僅需要使用 HTML 編寫更多內容,還需要閱讀更多內容。 使用 Pug,沒有開始和結束尖括號,也沒有結束標記。 因此,您編寫和閱讀的代碼要少得多。
例如,這是一個 HTML 表格:
<table> <thead> <tr> <th>Country</th> <th>Capital</th> <th>Population</th> <th>Currency</th> </tr> </thead> <tbody> <tr> <td>Canada</td> <td>Ottawa</td> <td>37.59 million</td> <td>Canadian Dollar</td> </tr> <tr> <td>South Africa</td> <td>Cape Town, Pretoria, Bloemfontein</td> <td>57.78 million</td> <td>South African Rand</td> </tr> <tr> <td>United Kingdom</td> <td>London</td> <td>66.65 million</td> <td>Pound Sterling</td> </tr> </tbody> </table>
這就是 Pug 中同一張表的樣子:
table thead tr th Country th Capital(s) th Population th Currency tbody tr td Canada td Ottawa td 37.59 million td Canadian Dollar tr td South Africa td Cape Town, Pretoria, Bloemfontein td 57.78 million td South African Rand tr td United Kingdom td London td 66.65 million td Pound Sterling
對比兩個版本的表格,Pug 看起來比 HTML 乾淨很多,代碼可讀性也更好。 儘管在這個小示例中可以忽略不計,但您在 Pug 表中編寫的行數比在 HTML 表中少七行。 隨著您隨著時間的推移為項目創建更多模板,您最終會累積使用 Pug 編寫更少的代碼。
除了 Angular 模板語言提供的功能之外,Pug 還擴展了您可以在模板中實現的功能。 借助功能(例如 mixins、文本和屬性插值、條件、迭代器等),您可以使用 Pug 更簡單地解決問題,而不是編寫整個單獨的組件或導入依賴項並設置指令來滿足需求。
哈巴狗的一些特點
Pug 提供了廣泛的功能,但您可以使用哪些功能取決於您如何將 Pug 集成到您的項目中。 以下是一些您可能會覺得有用的功能。
- 使用
include
將外部 Pug 文件添加到模板中。
例如,假設您想要一個更簡潔的模板,但不覺得需要創建額外的組件。 您可以從模板中取出部分並將它們放入部分模板中,然後將它們重新包含到原始模板中。
例如,在此主頁組件中,“關於”和“服務”部分位於外部文件中,並包含在主頁組件中。//- home.component.pug h1 Leone and Sons h2 Photography Studio include partials/about.partial.pug include partials/services.partial.pug
//- about.partial.pug h2 About our business p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
//- services.partial.pug h2 Services we offer P Our services include: ul li Headshots li Corporate Event Photography
- 使用 mixins 重用代碼塊。
例如,假設您想重用代碼塊來創建一些按鈕。 您將使用 mixin 重用該代碼塊。mixin menu-button(text, action) button.btn.btn-sm.m-1('(click)'=action)&attributes(attributes)= text +menu-button('Save', 'saveItem()')(class="btn-outline-success") +menu-button('Update', 'updateItem()')(class="btn-outline-primary") +menu-button('Delete', 'deleteItem()')(class="btn-outline-danger")
- 條件可以很容易地根據條件是否滿足來顯示代碼塊和註釋。
- var day = (new Date()).getDay() if day == 0 p We're closed on Sundays else if day == 6 p We're open from 9AM to 1PM else p We're open from 9AM to 5PM
- 諸如
each
和while
之類的迭代器提供了迭代功能。ul each item in ['Eggs', 'Milk', 'Cheese'] li= item ul while n < 5 li= n++ + ' bottles of milk on the wall'
- 內聯 JavaScript 可以用 Pug 模板編寫,如上面的示例所示。
- 插值是可能的,並擴展到標籤和屬性。
- var name = 'Charles' p Hi! I'm #{name}. p I'm a #[strong web developer]. a(href='https://about.me/${name}') Get to Know Me
- 過濾器允許在 Pug 模板中使用其他語言。
例如,您可以在安裝 JSTransformer Markdown 模塊後在 Pug 模板中使用 Markdown。:markdown-it # Charles the Web Developer ![Image of Charles](https://charles.com/profile.png) ## About Charles has been a web developer for 20 years at **Charles and Co Consulting.**
這些只是 Pug 提供的一些功能。 您可以在 Pug 的文檔中找到更廣泛的功能列表。
如何在 Angular 應用程序中使用 Pug
對於使用 Angular CLI 6 及更高版本的新應用和現有應用,您需要安裝ng-cli-pug-loader
。 它是 Pug 模板的 Angular CLI 加載器。
對於新組件和項目
- 安裝
ng-cli-pug-loader
。ng add ng-cli-pug-loader
- 根據您的喜好生成組件。
例如,假設我們正在生成一個主頁組件:ng gc home --style css -m app
- 將 HTML 文件擴展名
.html
更改為 Pug 擴展名.pug
。 由於最初生成的文件包含 HTML,您可以選擇刪除其內容並使用 Pug 重新開始。 但是,HTML 仍然可以在 Pug 模板中運行,因此您可以保持原樣。 - 在組件裝飾器中將模板的擴展名更改為
.pug
。@Component({ selector: 'app-component', templateUrl: './home.component.pug', styles: ['./home.component.css'] })
對於現有組件和項目
- 安裝
ng-cli-pug-loader
。ng add ng-cli-pug-loader
- 安裝 html2pug CLI 工具。 此工具將幫助您將 HTML 模板轉換為 Pug。
npm install -g html2pug
- 要將 HTML 文件轉換為 Pug,請運行:
html2pug -f -c < [HTML file path] > [Pug file path]
-f
以指示html2pug
它不應該將它生成的模板包裝在html
和body
標記中。-c
標誌讓html2pug
知道在轉換過程中元素的屬性應該用逗號分隔。 我將在下面介紹為什麼這很重要。 - 在組件裝飾器中將模板的擴展名更改為
.pug
,如對於新組件和項目部分所述。 - 運行服務器以檢查 Pug 模板的呈現方式是否沒有問題。
如果有問題,請使用 HTML 模板作為參考,找出可能導致問題的原因。 這有時可能是縮進問題或未引用的屬性,儘管很少見。 一旦您對 Pug 模板的呈現方式感到滿意,請刪除 HTML 文件。
從 HTML 遷移到 Pug 模板時要考慮的事項
您將無法將內聯 Pug 模板與ng-cli-pug-loader
一起使用。 這只會渲染 Pug 文件,不會渲染組件裝飾器中定義的內聯模板。 所以所有現有的模板都需要是外部文件。 如果您有任何內聯 HTML 模板,請為它們創建外部 HTML 文件並使用html2pug
將它們轉換為 Pug。
轉換後,您可能需要修復使用綁定和屬性指令的模板。 ng-cli-pug-loader
要求 Angular 中的綁定屬性名稱用單引號或雙引號括起來或用逗號分隔。 解決此問題的最簡單方法是將-c
標誌與html2pug
一起使用。 但是,這僅解決了具有多個屬性的元素的問題。 對於具有單個屬性的元素,只需使用引號。
如果您選擇創建一個,這裡描述的許多設置可以使用任務運行器或腳本或自定義 Angular 示意圖進行自動化,以進行大規模轉換。 如果您有幾個模板並且想要進行增量轉換,最好一次只轉換一個文件。
Pug 模板中的 Angular 模板語言語法
在大多數情況下,Angular 模板語言語法在 Pug 模板中保持不變,但是,當涉及到綁定和一些指令(如上所述)時,您需要使用引號和逗號,因為()
、 []
和[()]
干擾 Pug 模板的編譯。 這裡有一些例子:
//- [src], an attribute binding and [style.border], a style binding are separated using a comma. Use this approach when you have multiple attributes for the element, where one or more is using binding. img([src]='itemImageUrl', [style.border]='imageBorder') //- (click), an event binding needs to be enclosed in either single or double quotes. Use this approach for elements with just one attribute. button('(click)'='onSave($event)') Save
像ngClass
、 ngStyle
和ngModel
這樣的屬性指令必須放在引號中。 *ngIf
、 *ngFor
、 *ngSwitchCase
和*ngSwitchDefault
等結構指令也需要放在引號中或與逗號一起使用。 模板引用變量(例如#var
)不會干擾 Pug 模板編譯,因此不需要引號或逗號。 {{ }}
中的模板表達式不受影響。
在 Angular 模板中使用 Pug 的缺點和權衡
儘管 Pug 很方便並且改進了工作流程,但使用它也有一些缺點,並且在使用ng-cli-pug-loader
時需要考慮一些權衡。
文件不能使用include
包含在模板中,除非它們以.partial.pug
或.include.pug
結尾或稱為mixins.pug
。 除此之外,模板繼承不適用於ng-cli-pug-loader
,因此,儘管這是一個有用的 Pug 功能,但無法使用塊、前置和附加 Pug 代碼。
Pug 文件必須手動創建,因為 Angular CLI 只生成帶有 HTML 模板的組件。 您將需要刪除生成的 HTML 文件並創建一個 Pug 文件或僅更改 HTML 文件擴展名,然後更改組件裝飾器中的templateUrl
。 儘管這可以使用腳本、原理圖或任務運行程序自動完成,但您必須實施解決方案。
在較大的預先存在的 Angular 項目中,從 HTML 模板切換到 Pug 模板在某些情況下涉及大量工作和復雜性。 進行切換會導致大量破壞代碼,需要逐個文件或使用自定義工具自動修復。 元素中的綁定和一些 Angular 指令需要用逗號引用或分隔。
不熟悉 Pug 的開發人員必須先學習語法,然後才能將其整合到項目中。 Pug 不僅僅是沒有尖括號和結束標籤的 HTML,它還涉及學習曲線。
當編寫 Pug 並在 Angular 模板中使用它的功能時, ng-cli-pug-loader
不會讓 Pug 模板訪問組件的屬性。 因此,這些屬性不能用作變量、條件、迭代器和內聯代碼。 Angular 指令和模板表達式也無法訪問 Pug 變量。 例如,使用 Pug 變量:
//- app.component.pug - var shoppingList = ['Eggs', 'Milk', 'Flour'] //- will work ul each item in shoppingList li= item //- will not work because shoppingList is a Pug variable ul li(*ngFor="let item of shoppingList") {{item}}
這是一個帶有組件屬性的示例:
//- src/app/app.component.ts export class AppComponent{ shoppingList = ['Eggs', 'Milk', 'Flour']; }
//- app.component.pug //- will not work because shoppingList is a component property and not a Pug variable ul each item in shoppingList li= item //- will work because shoppingList is a property of the component ul li(*ngFor="let item of shoppingList") {{item}}
最後, index.html
不能是 Pug 模板。 ng-cli-pug-loader
不支持這個。
結論
Pug 可能是在 Angular 應用程序中使用的一個了不起的資源,但它確實需要一些投資來學習和集成到一個新的或預先存在的項目中。 如果您準備好迎接挑戰,您可以查看 Pug 的文檔以了解有關其語法的更多信息並將其添加到您的項目中。 儘管ng-cli-pug-loader
是一個很棒的工具,但它在某些方面可能有所欠缺。 要定制 Pug 在您的項目中的工作方式,請考慮創建一個滿足您項目要求的 Angular 示意圖。