版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
基于react的組件庫(kù)主題設(shè)計(jì)方案基于react設(shè)計(jì)與開(kāi)發(fā)的組件庫(kù)主題方案,以HippyReact主題方案設(shè)計(jì)為例需求背景單一的視覺(jué)不再滿足用戶體驗(yàn)需求,為提高用戶體驗(yàn),提高應(yīng)用體驗(yàn)口碑,同時(shí)提高開(kāi)發(fā)者效率,我們希望提高組件庫(kù)的可定制化,因此提供換膚功能以及多種類(lèi)組件中的樣式定制功能,允許用戶將應(yīng)用切換不同主題風(fēng)格的皮膚,也允許開(kāi)發(fā)者對(duì)指定組件進(jìn)行樣式改造。設(shè)計(jì)目標(biāo)性能一個(gè)方案的落地前提得有性能的保障,不重新初始化視圖,避免出現(xiàn)閃屏、卡頓等性能缺陷現(xiàn)象,同時(shí)也要保障功能穩(wěn)定,不能存在部分組件不按預(yù)期切換主題現(xiàn)象。可維護(hù)性組件庫(kù)需不斷迭代完善,應(yīng)避免過(guò)多的條件判斷,避免在單個(gè)組件上有過(guò)多的主題特殊邏輯,主題的設(shè)置和組件的實(shí)現(xiàn)應(yīng)解耦,保證后續(xù)可維護(hù)可擴(kuò)展。可配置可配置分為兩部分,一部分為可配置任意全局統(tǒng)一的樣式變量,或者某個(gè)組件的局部樣式;另一部分為強(qiáng)制模式,即指定部分組件不跟隨主題變化而變化,保留著本身一種樣式。易用性提供快捷接入主題的接口,降低學(xué)習(xí)成本和時(shí)間成本。粒度細(xì)分組件層面的主題定制、整套組件庫(kù)的主題定制。開(kāi)發(fā)者可以修改全局樣式,比如更換全局中字號(hào)的字體大小,也可以局部修改樣式,比如按鈕組件A的邊框顏色。樣式提取暴露出提取當(dāng)前整套樣式的接口,方便開(kāi)發(fā)者提取指定樣式做二次操作。比如開(kāi)發(fā)者需要提取當(dāng)前主題顏色作為視圖背景色,可從組件庫(kù)中獲取。樣式可定制內(nèi)容,包括但不限于:顏色:品牌色、默認(rèn)背景色、通用背景色、基本文本顏色、輔助文本顏色、鏈接色文本:文本大小,字重,字體間距等按鈕:圓角大小,按鈕尺寸,邊框尺寸等圖片:圖片尺寸,圓角大小等技術(shù)選型主題定制是大多數(shù)組件庫(kù)都會(huì)提供的一個(gè)核心樣式相關(guān)的功能,技術(shù)選項(xiàng)上需要考慮的兩點(diǎn):如何生成一份全局樣式配置表組件如何獲取樣式配置表針對(duì)以上兩點(diǎn),我們做了一些分析:如何生成一份全局樣式配置表目前各類(lèi)組件庫(kù)最常用的是以下兩種方案:借助gulp/webpack等打包工具相關(guān)的插件,配置需要定制的樣式變量,在打包時(shí)覆蓋對(duì)應(yīng)變量值。重寫(xiě)樣式,覆蓋樣式配置表,生成新的全局樣式配置表。在我們實(shí)現(xiàn)的hippy-react-ui中我們并沒(méi)有提供打包的能力,而是把這部分移交到業(yè)務(wù)側(cè)處理,原因是現(xiàn)在大部分業(yè)務(wù)發(fā)布時(shí)都會(huì)對(duì)業(yè)務(wù)進(jìn)行打包處理,業(yè)務(wù)側(cè)可能靈活設(shè)置打包配置內(nèi)容,而不受限于組件庫(kù)打包,另一方面是讓業(yè)務(wù)側(cè)使用組件時(shí)可以快速定位組件內(nèi)部結(jié)構(gòu),方便排查使用過(guò)程中遇到的問(wèn)題。因此我們選用了以上第二種方案,提供一份默認(rèn)的樣式配置表,而業(yè)務(wù)側(cè)可以寫(xiě)入重新樣式對(duì)其覆蓋。組件如何獲取樣式配置表組件庫(kù)是基于hippy-react設(shè)計(jì)開(kāi)發(fā)的,hippy-react提供的數(shù)據(jù)的傳遞有兩種:通過(guò)props屬性自上而下(由父及子)進(jìn)行傳遞Context提供了一種在組件之間共享值的方式,不必顯式地通過(guò)組件樹(shù)的逐層傳遞props第一個(gè)方案使用簡(jiǎn)單,只需要將樣式從根節(jié)點(diǎn)往下一層層傳遞即可,但它的缺點(diǎn)也是需要一層層傳遞。我們的組件庫(kù)中,復(fù)合組件很多,比如列表組件中用到了按鈕組件,按鈕組件中用到了文本組件,這要求每個(gè)組件都需要獲取一遍props再往下傳遞,不僅加大開(kāi)發(fā)成本,對(duì)影響了后續(xù)開(kāi)發(fā)的可維護(hù)性。而第二個(gè)方案,我們只需要使用context提供主題的提供者和消費(fèi)者,在需要使用主題的組件中注入即可,但它有個(gè)缺點(diǎn):每次更新context的內(nèi)容,都會(huì)將所有消費(fèi)到主題的組件重新更新一遍。而針對(duì)context的缺點(diǎn),我們可以放下這個(gè)顧慮,因?yàn)橹黝}本身也是只消費(fèi)一遍,在切換主題的時(shí)候進(jìn)行消費(fèi),而不是高頻的去使用。因此組件獲取樣式配置表是通過(guò)context的方式進(jìn)行獲取。設(shè)計(jì)方案通過(guò)上面技術(shù)的選型,我們確定了兩點(diǎn):重寫(xiě)樣式,覆蓋樣式配置表,生成新的全局樣式配置表組件通過(guò)Context提高的組件之間共享值的方式,獲取樣式配置表生成樣式配置表以上是生成全局樣式表的過(guò)程,在講解流程前需補(bǔ)充說(shuō)明上圖中深色/淺色主題:組件庫(kù)內(nèi)置兩份主題色,主題的切換主要是顏色部分的切換,提供兩種主題的原因是我們盡可能通用化配色,比如以下幾個(gè)例子,背景色/背景圖片我們可以隨意替換,但作用在其之上的內(nèi)容,簡(jiǎn)單分為深/淺兩種方案基本可以適用到大部分場(chǎng)景。樣式優(yōu)先級(jí)組件庫(kù)自帶的樣式分為三部分:跟主題相關(guān)的深色主題和淺色主題,還有與主題切換無(wú)關(guān)的其他樣式,在業(yè)務(wù)側(cè)未指定主題時(shí),組件庫(kù)默認(rèn)使用淺色主題的顏色配置表+其他可配置的默認(rèn)樣式值,如字體大小,字重等,業(yè)務(wù)側(cè)可以重寫(xiě)樣式,最終生成的樣式表作為提供者Provider給到各個(gè)組件使用。我們暴露一個(gè)屬性value={}給業(yè)務(wù)側(cè)賦值給組件庫(kù),業(yè)務(wù)側(cè)可以在對(duì)象中傳入指定的主題,比如value={theme:"light"}或者value={theme:"dark"},我們提供一個(gè)便利,業(yè)務(wù)側(cè)可以直接傳入value="light"或value="dark"。如果希望針對(duì)某個(gè)樣式值進(jìn)行重寫(xiě),可以value={textBaseColor:"#555555"}。在組件庫(kù)中,我們根據(jù)業(yè)務(wù)側(cè)傳入的自定義內(nèi)容進(jìn)行判斷且合并成新的樣式配置表:functiongetStyle(style){if(style==="light"){returnuseTheme(lightStyleSheet);}elseif(style==="dark"){returnuseTheme(darkStyleSheet);}else{constthemeStyle=style&&style.theme==="dark"?darkStyleSheet:lightStyleSheet;returnuseTheme({...themeStyle,...style});}};該函數(shù)中style即為業(yè)務(wù)側(cè)傳入的value,首先判斷style是否為主題(light/dark),是即返回對(duì)應(yīng)主題表。useTheme是一個(gè)合并樣式的方法,參數(shù)是樣式對(duì)象。functionuseTheme(args={}){returnObject.assign({},defaultStyle,args);}可以看到這個(gè)方法只是一個(gè)合并的操作,defaultStyle指向了默認(rèn)的樣式表。Context傳遞共享值以上為樣式合并的過(guò)程,接下來(lái)我們需要將樣式配置表作為樣式提供者(Provider)傳遞到各個(gè)消費(fèi)者(consumer)各個(gè)組件中。Context提供了一個(gè)無(wú)需為每層組件手動(dòng)添加props,就能在組件樹(shù)間進(jìn)行數(shù)據(jù)傳遞的方法。提供主題的Provider(提供者)和Consumer(消費(fèi)者),我們通過(guò)React.createContext()創(chuàng)建上下文,使得Provider和Consumer可以接收和獲取同一信息。constThemeContext=React.createContext(defaultTheme);Provider:用于接收主題和樣式參數(shù),并與默認(rèn)樣式合集、深/淺色主題樣式合并。如上文所提到的,我們?cè)试S給組件傳入指定主題變量:"dark"或者"light",也允許傳入自定義樣式對(duì)象,如:{hiColorTheme:"#666666"},下圖展示樣式獲取過(guò)程,根據(jù)優(yōu)先級(jí)(用戶自定義樣式>用戶自定義主題>默認(rèn)主題)會(huì)生成一份配置表,而我們所有允許定制的樣式,樣式屬性值均從配置表獲取。//ThemeProvider:將樣式合集寫(xiě)入value提供給消費(fèi)者constThemeProvider=(props:ThemeProviderProps)=>{letstyle=getStyle(props.value);return<ThemeContext.Providervalue={style}>{props.children}</ThemeContext.Provider>;};Consumer:用于獲取樣式合集并提供給子組件Consumer獲取到的樣式合集作為生成子組件的函數(shù)參數(shù),這就要求子組件是以函數(shù)的方式獲取樣式合集,后面如何使用中會(huì)對(duì)應(yīng)介紹,如下classThemeConsumerextendsReact.Component{render(){return(<ThemeContext.Consumer>//children是一個(gè)函數(shù),而非組件{style=>{returnps.children(style);}}</ThemeContext.Consumer>);}}組件接收樣式表如上圖,我們將Provider包圍在最外層,建議在根節(jié)點(diǎn)使用,根據(jù)需要也可包裹置于局部組件。在Provider中的任意Consumer均可獲取到同一份樣式表,當(dāng)Provider更改自定義值時(shí),在任意訂閱的地方均可以獲取到最新樣式表,從而更新節(jié)點(diǎn)。在根節(jié)點(diǎn)使用Provider,并引入自定義樣式或者指定主題<Providertheme={{theme:"dark",defaultFontSize:18}}><HiText/><HiList/></Provider>Text組件<Consumer>{(themeStyle)=>{return(<Textstyle={{fontSize:themeStyle.defaultFontSize}}>Text組件</Text>);}}</Consumer>List組件<Consumer>{(themeStyle)=>{return(<View><Textstyle={{fontSize:themeStyle.defaultFontSize}}>List組件</Text><HiText/></View>);}}</Consumer>強(qiáng)制模式強(qiáng)制模式即當(dāng)用戶切換主題時(shí),該模式下的組件不會(huì)跟隨主題變化。何時(shí)會(huì)使用到該模式呢?例如上圖,是在淺色主題下的展示,但藍(lán)框中因?yàn)橛泄潭ǖ谋尘皥D存在,我們不希望它跟隨主題色切換文本顏色,而是固定為深色模式下的淺色文本顏色,就需要用到強(qiáng)制模式讓它主題固定下來(lái)。
強(qiáng)制模式的實(shí)現(xiàn)是采用了攔截Provider傳遞給Consumer的方式,如下圖:例如文本組件中使用了Consumer接收全局樣式,但如果業(yè)務(wù)使用了Text組件,并賦予了主題屬性,那么我們會(huì)將主題屬性告知Consumer,在Consumer中,局部組件提供主題屬性優(yōu)先級(jí)高于Provider提供的主題屬性值。renderChildren(style:any){letchildren=ps.children(style);if(children&&ps&&ps.theme){//判斷局部逐漸是否傳遞了主題屬性letpartStyle=getStyle(ps.theme);children=ps.children(partStyle);}returnchildren;}暴露樣式表上文中提到主題的切換均作用于組件庫(kù)中的組件,當(dāng)業(yè)務(wù)不需要組件而需要獲取樣式表的內(nèi)容進(jìn)行其他操作時(shí),我們需要給到業(yè)務(wù)側(cè)當(dāng)前的主題樣式表,使得用組件庫(kù)的業(yè)務(wù)可以做更多的界面統(tǒng)一。于是我們?cè)谥黝}Provider提供了一個(gè)靜態(tài)變量,允許業(yè)務(wù)獲取classThemeProviderextendsComponent<ThemeProviderProps>{staticstyleConfig:DefaultStyle;render(){conststyle=getStyle(ps.value);ThemeProvider.styleConfig=style;//暴露主題配置表......}}如何使用Provider引入使用:將Provider置于根節(jié)點(diǎn)上//app.js<Providertheme="dark"></Provider>theme屬性使用定制主題theme可傳入"dark"或者"light"<Providertheme="light"></Provider>定制樣式theme可以重寫(xiě)樣式表中默認(rèn)的樣式,如需修改默認(rèn)字體中字號(hào)的大小<Providertheme={{hiFontSizeM:20}}></Provider>定制主題+定制樣式<Providertheme={{theme:"dark",hiFontSizeM:20}}></Provider>全局定制背景色默認(rèn)使用主題背景色。優(yōu)先級(jí):style屬性>更改配置表定制背景色>默認(rèn)主題背景色//更改配置表定制背景色:背景色使用的是樣式表中的hiBgColor值<Providertheme={{hiBgColor:"#666666"}}></Provider>//style屬性更改背景色<Providerstyle={{backgroundColor:"#666666"}}></Provider>強(qiáng)制模式importHiTextfrom"../HiText";<HiTexttheme="dark">default(Text28A)</HiText><HiTexttheme={{hiBgColor:"#666666"}}>default(Text28A)</HiText>獲取樣式配置表//引入ProviderletstyleConfig=Provider.styleConfig;重點(diǎn)問(wèn)題解決兼容新舊SDK主題設(shè)計(jì)核心用到了hippy-react的Context,這是hippy-react2.0.3之后提供的API,針對(duì)SDK未升級(jí)的舊業(yè)務(wù),我們需要兼容處理,避免報(bào)錯(cuò)。組件庫(kù)采用的是判斷版本號(hào)和檢查是否有Context判斷該版本是否支持主題切換constThemeContext=React.createContext?React.createContext(defaultStyle):null;constIS_SUPPORT_THEME=((HippyReact&&HippyReact.version&&versionCompare("2.0.3",HippyReact.version)))&&ThemeContext;對(duì)于低版本使用到主題功能的部分,我們同樣需要給到指定的樣式表Provider兼容方式:constThemeProvider=(props:ThemeProviderProps)=>{conststyle=getStyle(props.value);if(IS_SUPPORT_THEME){//支持主題切換,使用ContextAPIreturn(<View{...props}style={[{backgroundColor:style.hiBgColor||"#FFFFFF"},props.style]}key={style.type}><ThemeContext.Providervalue={style}>{props.children}</ThemeContext.Provider></View>);}else{//不支持主題切換,返回Provider下的children內(nèi)容return(<View{...props}style={[{backgroundColor:style.hiBgColor||"#FFFFFF"},props.style]}key={style.type}>{props.children}</View>);}};Consumer兼容方式:classThemeConsumerextendsReact.Component<ThemeConsumerProps>{staticdefaultProps:ThemeConsumerProps={children:()=>{}
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版團(tuán)購(gòu)工業(yè)地產(chǎn)協(xié)議書(shū)3篇
- 2024職業(yè)技能拓展訓(xùn)練合同
- 二零二五年度臨時(shí)道路建設(shè)臨建工程合同范本2篇
- 2025年度珠寶品牌授權(quán)與連鎖經(jīng)營(yíng)合同范本2篇
- 二零二五版房地產(chǎn)項(xiàng)目市場(chǎng)調(diào)研與策劃咨詢服務(wù)合同范本3篇
- 二零二五年度農(nóng)副產(chǎn)品電商平臺(tái)數(shù)據(jù)分析與應(yīng)用合同
- 2025年度智能穿戴設(shè)備代生產(chǎn)加工合同范本4篇
- 2024政府機(jī)關(guān)信息化系統(tǒng)運(yùn)維服務(wù)詢價(jià)采購(gòu)合同3篇
- 個(gè)體餐飲店合伙人股權(quán)回購(gòu)協(xié)議模板版B版
- 二零二五年度住宅樓屋頂綠化工程合同3篇
- 2024至2030年中國(guó)膨潤(rùn)土行業(yè)投資戰(zhàn)略分析及發(fā)展前景研究報(bào)告
- 【地理】地圖的選擇和應(yīng)用(分層練) 2024-2025學(xué)年七年級(jí)地理上冊(cè)同步備課系列(人教版)
- (正式版)CB∕T 4552-2024 船舶行業(yè)企業(yè)安全生產(chǎn)文件編制和管理規(guī)定
- JBT 14588-2023 激光加工鏡頭 (正式版)
- 2024年四川省成都市樹(shù)德實(shí)驗(yàn)中學(xué)物理八年級(jí)下冊(cè)期末質(zhì)量檢測(cè)試題含解析
- 九型人格與領(lǐng)導(dǎo)力講義
- 廉潔應(yīng)征承諾書(shū)
- 2023年四川省成都市中考物理試卷真題(含答案)
- 泵車(chē)述職報(bào)告
- 2024年山西文旅集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 恢復(fù)中華人民共和國(guó)國(guó)籍申請(qǐng)表
評(píng)論
0/150
提交評(píng)論