理想情況下,項目擁有無限資源和時間。團隊將使用經過深思熟慮且高度優化的UX 設計開始編碼。開發人員之間將就最佳樣式方法達成共識。團隊中將有一位或多位CSS 專家,他們可以確保功能和样式可以同時推出,而不會變成一團糟。
我確實在大型企業環境中見過這種情況。這是一件美好的事情。本文不適用於這些人。
另一方面,小型初創公司資金為零,只有一到兩位前端開發人員,而且展示某些功能的時間非常短。它不必看起來完美,但至少應該在台式機、平板電腦和移動設備上合理地呈現。這使他們能夠將其展示給顧問和早期用戶;甚至可能是對該概念表示感興趣的潛在投資者。一旦他們從銷售和/或投資中獲得一些現金流,他們就可以獲得專門的UX 設計師並改進界面。
以下內容適用於後一組人員。
項目啟動會議
讓我們發明一家公司來啟動項目。
Solar Excursions 是一家小型旅行社,旨在服務於近未來蓬勃發展的太空旅遊業。
我們的小型開發團隊已同意將React 用於UI。我們的一位前端開發人員非常喜歡Sass,而另一位則迷戀於JavaScript 中的CSS。但是他們很難完成最初的衝刺目標;當然沒有時間爭論最佳的樣式方法。兩位編碼員都同意,從長遠來看,選擇並不重要,只要它得到一致執行即可。他們確信,現在在壓力下從頭開始實現樣式將導致技術債務,以後必須清理。
經過一番討論,團隊選擇規劃一個或多個“樣式重構”衝刺。現在,我們將專注於使用React-Bootstrap 在屏幕上顯示一些內容。這樣,我們就可以快速構建有效的桌面和移動佈局,而無需大費周章。
在前端樣式上花費的時間越少越好,因為我們還需要將UI 連接到我們的後端開發人員將要推出的服務。而且,隨著我們的應用程序架構開始成形,兩位前端開發人員都同意對其進行單元測試非常重要。他們有很多事情要做。
根據我與當權者的討論,作為一名專門的項目經理,我至少在Balsamiq 上辛苦工作了十分鐘,為團隊提供了台式機和移動設備上預訂頁面的模型。我認為他們將在中間滿足平板電腦的要求,並且看起來很合理。
第零次沖刺:審查會議
到處都是比薩餅!團隊非常努力地實現了其目標,我們現在有一個佈局近似於模型的預訂頁面。服務的架構正在形成,但在我們可以將其連接到UI 之前還有很長的路要走。在此期間,前端開發人員正在使用硬編碼的模擬數據結構。
以下是我們迄今為止的UI 代碼:
這都是簡單的React。我們正在使用一些Hooks 熱門技術,但對你們大多數人來說,這可能已經過時了。
需要注意的關鍵要點是,我們的五個應用程序組件中有四個導入並使用了來自react-bootstrap 的組件。只有主要的App 組件不受影響。這是因為它只是使用我們的自定義組件組合頂級視圖。
<code>// App.js imports import React, { useState } from "react"; import Navigation from "./Navigation"; import Page from "./Page"; // Navigation.js imports import React from "react"; import { Navbar, Dropdown, Nav } from "react-bootstrap"; // Page.js imports import React from "react"; import PosterCarousel from "./PosterCarousel"; import DestinationLayout from "./DestinationLayout"; import { Container, Row, Col } from "react-bootstrap"; // PosterCarousel.js imports import React from "react"; import { Alert, Carousel, Image } from "react-bootstrap"; // DestinationLayout.js imports import React, { useState, useEffect } from "react"; import { Button, Card, Col, Container, Dropdown, Jumbotron, ListGroup, Row, ToggleButtonGroup, ToggleButton } from "react-bootstrap";</code>
使用Bootstrap 快速行動的決定使我們能夠實現衝刺目標,但我們已經在積累技術債務。這只是四個受影響的組件,但隨著應用程序的增長,很明顯,我們計劃的“樣式重構”衝刺將變得越來越困難。我們甚至沒有對這些組件進行太多自定義。一旦我們擁有數十個組件,所有組件都使用Bootstrap 並使用大量內聯樣式來美化它們,將它們重構以刪除react-bootstrap 依賴項將是一個非常可怕的主張。
與其構建更多預訂管道頁面,團隊決定我們將花費下一個衝刺來隔離自定義組件工具包中的react-bootstrap 使用情況,因為我們的服務仍在構建中。應用程序組件將僅使用此工具包中的組件。這樣,當我們從react-bootstrap 中分離出來時,這個過程就會容易得多。我們不必在整個應用程序中重構三十個react-bootstrap Button 的用法,我們只需重寫KitButton 組件的內部即可。
第一次沖刺:審查會議
好吧,這很容易。擊掌。 UI 的視覺外觀沒有變化,但我們現在有一個“kit”文件夾,它是我們React 源代碼中“components”的同級文件夾。它有很多文件,例如KitButton.js,它基本上導出重命名的react-bootstrap 組件。
我們工具包中的一個示例組件如下所示:
<code>// KitButton.js import { Button, ToggleButton, ToggleButtonGroup } from "react-bootstrap"; export const KitButton = Button; export const KitToggleButton = ToggleButton; export const KitToggleButtonGroup = ToggleButtonGroup;</code>
我們將所有工具包組件打包到這樣的模塊中:
<code>// kit/index.js import { KitCard } from "./KitCard"; import { KitHero } from "./KitHero"; import { KitList } from "./KitList"; import { KitImage } from "./KitImage"; import { KitCarousel } from "./KitCarousel"; import { KitDropdown } from "./KitDropdown"; import { KitAttribution } from "./KitAttribution"; import { KitNavbar, KitNav } from "./KitNavbar"; import { KitContainer, KitRow, KitCol } from "./KitContainer"; import { KitButton, KitToggleButton, KitToggleButtonGroup } from "./KitButton"; export { KitCard, KitHero, KitList, KitImage, KitCarousel, KitDropdown, KitAttribution, KitButton, KitToggleButton, KitToggleButtonGroup, KitContainer, KitRow, KitCol, KitNavbar, KitNav };</code>
現在我們的應用程序組件完全沒有react-bootstrap。以下是受影響組件的導入:
<code>// Navigation.js imports import React from "react"; import { KitNavbar, KitNav, KitDropdown } from "../kit"; // Page.js imports import React from "react"; import PosterCarousel from "./PosterCarousel"; import DestinationLayout from "./DestinationLayout"; import { KitContainer, KitRow, KitCol } from "../kit"; // PosterCarousel.js imports import React from "react"; import { KitAttribution, KitImage, KitCarousel } from "../kit"; // DestinationLayout.js imports import React, { useState, useEffect } from "react"; import { KitCard, KitHero, KitList, KitButton, KitToggleButton, KitToggleButtonGroup, KitDropdown, KitContainer, KitRow, KitCol } from "../kit";</code>
以下是我們現在的前端代碼庫:
儘管我們將所有react 導入都包含在我們的工具包組件中,但我們的應用程序組件仍然依賴於react-bootstrap 實現,因為我們放置在工具包組件實例上的屬性與react-bootstrap 的屬性相同。這在重新實現工具包組件時會限制我們,因為我們需要遵守相同的API。例如:
<code>// 来自Navigation.js<kitnavbar bg="dark" fixed="top" variant="dark"></kitnavbar></code>
理想情況下,當我們實例化KitNavbar 時,我們不必添加那些react-bootstrap 特定的屬性。
前端開發人員承諾在繼續進行時將這些屬性重構出來,因為我們已經將它們識別為有問題的。任何對react-bootstrap 組件的新引用都將進入我們的工具包,而不是直接進入應用程序組件。
同時,我們將我們的模擬數據與服務器工程師共享,服務器工程師正在努力構建單獨的服務器環境、實現數據庫模式並向我們公開一些服務。
這給了我們時間在下一個衝刺中為我們的UI 添加一些光澤——這很好,因為當權者希望看到每個目的地的單獨主題。當用戶瀏覽目的地時,我們需要更改UI 配色方案以匹配顯示的旅行海報。此外,我們希望嘗試改進這些組件,以開始發展我們自己的外觀和感覺。一旦我們有一些收入,我們將請設計師進行全面檢修,但希望我們能夠為早期用戶找到一個合適的方案。
第二次沖刺:審查會議
哇!團隊在這個衝刺中確實竭盡全力。我們獲得了每個目的地的主題、自定義組件以及從應用程序組件中刪除了許多殘留的react-bootstrap API 實現。
以下是現在的桌面外觀:
為了實現這一點,前端開發人員引入了Styled Components 庫。它使為各個工具包組件設置樣式以及添加對多個主題的支持變得輕而易舉。
讓我們看看他們本衝刺中的一些亮點。
首先,對於導入字體和設置頁面正文樣式之類的全局內容,我們有一個名為KitGlobal 的新工具包組件。
<code>// KitGlobal.js import { createGlobalStyle } from "styled-components"; export const KitGlobal = createGlobalStyle` body { @import url('https://fonts.googleapis.com/css?family=Orbitron:500|Nunito:600|Alegreya Sans SC:700'); background-color: ${props => props.theme.foreground}; overflow-x: hidden; } `;</code>
它使用createGlobalStyle 輔助函數來定義body 元素的CSS。它從Google 導入我們所需的網絡字體,將背景顏色設置為當前主題的“前景”值,並關閉x 方向上的溢出以消除討厭的水平滾動條。我們在App 組件的render 方法中使用KitGlobal 組件。
同樣在App 組件中,我們從../theme 導入ThemeProvider 來自styled-components,以及名為“themes”的內容。我們使用React 的useState 將初始主題設置為themes.luna,並使用React 的useEffect 在“destination”更改時調用setTheme。返回的組件現在包裝在ThemeProvider 中,後者將“theme”作為prop 傳遞。以下是完整的App 組件。
<code>// App.js import React, { useState, useEffect } from "react"; import { ThemeProvider } from "styled-components"; import themes from "../theme/"; import { KitGlobal } from "../kit"; import Navigation from "./Navigation"; import Page from "./Page"; export default function App(props) { const [destinationIndex, setDestinationIndex] = useState(0); const [theme, setTheme] = useState(themes.luna); const destination = props.destinations[destinationIndex]; useEffect(() => { setTheme(themes[destination.theme]); }, [destination]); return (<themeprovider theme="{theme}"><react.fragment><kitglobal></kitglobal><navigation destinationindex="{destinationIndex}" setdestinationindex="{setDestinationIndex}"></navigation><page destinationindex="{destinationIndex}" setdestinationindex="{setDestinationIndex}"></page></react.fragment></themeprovider> ); }</code>
KitGlobal 像任何其他組件一樣呈現。那裡沒有什麼特別的,只是body 標籤受到影響。 ThemeProvider 使用React Context API 將主題傳遞給任何需要它的組件(所有組件)。為了完全理解這一點,我們還需要看看主題究竟是什麼。
為了創建一個主題,我們的一位前端開發人員獲取了所有旅行海報,並通過提取突出的顏色為每個海報創建調色板。這相當簡單。
顯然,我們不會使用所有顏色。該方法主要是將最常用的兩種顏色命名為前景和背景。然後我們又取了三種顏色,通常從最淺到最深排列為accent1、accent2 和accent3。最後,我們選擇了兩種對比色來命名text1 和text2。對於上述目的地,這看起來像:
<code>// theme/index.js (部分列表) const themes = { ... mars: { background: "#a53237", foreground: "#f66f40", accent1: "#f8986d", accent2: "#9c4952", accent3: "#f66f40", text1: "#f5e5e1", text2: "#354f55" }, ... }; export default themes;</code>
一旦我們為每個目的地創建了一個主題,並且它被傳遞到所有組件(包括我們的應用程序組件現在從中構建的工具包組件),我們就需要使用styled-components 來應用這些主題顏色以及我們的自定義視覺樣式,例如面板角和“邊框輝光”。
這是一個簡單的示例,我們讓KitHero 組件將主題和自定義樣式應用於Bootstrap Jumbotron:
<code>// KitHero.js import styled from "styled-components"; import { Jumbotron } from "react-bootstrap"; export const KitHero = styled(Jumbotron)` background-color: ${props => props.theme.accent1}; color: ${props => props.theme.text2}; border-radius: 7px 25px; border-color: ${props => props.theme.accent3}; border-style: solid; border-width: 1px; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; font-family: "Nunito", sans-serif; margin-bottom: 20px; `;</code>
在這種情況下,我們可以使用styled-components 返回的內容,因此我們只需將其命名為KitHero 並導出即可。
當我們在應用程序中使用它時,它看起來像這樣:
<code>// DestinationLayout.js (部分代码) const renderHero = () => { return (<kithero></kithero></code><h2 id="destination-header"> {destination.header}</h2> <p>{destination.blurb}</p> <kitbutton>Book Your Trip Now!</kitbutton> ); };
然後還有更複雜的情況,我們希望預設react-bootstrap 組件上的一些屬性。例如,前面我們已經確定KitNavbar 組件具有一堆我們寧願不從應用程序的組件聲明中傳遞的react-bootstrap 屬性。
現在讓我們看看是如何處理的:
<code>// KitNavbar.js (部分代码) import React, { Component } from "react"; import styled from "styled-components"; import { Navbar } from "react-bootstrap"; const StyledBootstrapNavbar = styled(Navbar)` background-color: ${props => props.theme.background}; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; display: flex; flex-direction: horizontal; justify-content: space-between; font-family: "Nunito", sans-serif; `; export class KitNavbar extends Component { render() { const { ...props } = this.props; return ; } }</code>
首先,我們使用styled-components 創建一個名為StyledBootstrapNavbar 的組件。我們可以使用傳遞給styled-components 的CSS 來處理一些屬性。但是,為了繼續利用(目前)組件對屏幕頂部的可靠粘性(而其他所有內容都被滾動),我們的前端開發人員選擇繼續使用react-bootstrap 的fixed 屬性。為了做到這一點,我們必須創建一個KitNavbar 組件,該組件使用fixed=top 屬性呈現StyledBootstrapNavbar 的實例。我們還傳遞了所有props,其中包括它的子元素。
如果我們想通過默認值在工具包組件中顯式設置某些屬性,我們只需要創建一個單獨的類來呈現styled-component 的工作並將props 傳遞給它即可。在大多數情況下,我們只需命名和返回styled-component 的輸出並像上面對KitHero 所做的那樣使用它即可。
現在,當我們在應用程序的Navigation 組件中呈現KitNavbar 時,它看起來像這樣:
<code>// Navigation.js (部分代码) return (<kitnavbar><kitnavbarbrand><kitlogo></kitlogo> Solar Excursions</kitnavbarbrand> {renderDestinationMenu()}</kitnavbar> );</code>
最後,我們第一次嘗試將工具包組件從react-bootstrap 中重構出來。 KitAttribution 組件是一個Bootstrap Alert,就我們的目的而言,它只不過是一個普通的div。我們能夠輕鬆地重構以刪除其對react-bootstrap 的依賴性。
這是從上一個衝刺中出現的組件:
<code>// KitAttribution.js (使用react-bootstrap) import { Alert } from "react-bootstrap"; export const KitAttribution = Alert;</code>
這就是它現在的樣子:
<code>// KitAttribution.js import styled from "styled-components"; export const KitAttribution = styled.div` text-align: center; background-color: ${props => props.theme.accent1}; color: ${props => props.theme.text2}; border-radius: 7px 25px; border-color: ${props => props.theme.accent3}; border-style: solid; border-width: 1px; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; font-family: "Alegreya Sans SC", sans-serif; > a { color: ${props => props.theme.text2}; font-family: "Nunito", sans-serif; } > a:hover { color: ${props => props.theme.background}; text-decoration-color: ${props => props.theme.accent3}; } `;</code>
請注意,我們不再導入react-bootstrap,而是使用styled.div 作為組件基礎。它們不會都那麼容易,但這是一個過程。
以下是我們的團隊在本衝刺中進行的樣式和主題設計工作的結果:
在此處查看主題頁面本身。
結論
經過三個衝刺後,我們的團隊正在順利構建UI 的可擴展組件架構。
- 由於react-bootstrap,我們正在快速前進,但不再因此積累大量的技術債務。
- 由於styled-components,我們能夠實現多個主題(就像如今互聯網上的幾乎每個應用程序都具有深色和淺色模式一樣)。我們也不再像一個現成的Bootstrap 應用程序了。
- 通過實現一個包含所有對react-bootstrap 的引用的自定義組件工具包,我們可以根據需要進行重構。
在GitHub 上分叉最終代碼庫。
以上是迭代使用樣式組件的React設計的詳細內容。更多資訊請關注PHP中文網其他相關文章!

對於Astro,我們可以在構建過程中生成大部分網站,但是有一小部分服務器端代碼可以使用Fuse.js之類的搜索功能來處理搜索功能。在此演示中,我們將使用保險絲搜索一組個人“書籤”


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。