抄寫多語言組件,基於ice-plugin-fusion為iceworks的“ICE Design Pro”實現一個多主題切換功能 ...
最近一直處於半失業狀態,好多年沒有更新對前端的理解了,閑來看看前端技術的發展。因為一直是個草台班子,身兼多職東看看西看看,一直沒太搞清楚iceworks、ant design, fusion等等一堆阿裡系的開源項目。用了半小時用iceworks搭了一個react的模板出來,感覺好像自己突然成了react磚家似的,花了幾天時間像貓吃刺蝟一樣,難以下嘴。總是覺得“ICE Design Pro”沒有動態主題配置很不方便。摸索了兩天,算是磕磕絆絆的抄出了一個功能。那就仿照這“多語言”設置依葫蘆畫瓢整一個多主題配置吧。
在路徑“\src\layouts\BasicLayout\components\Header”下找到了index.jsx
import SelectLang from '@/components/SelectLang';
import SelectTheme from '@/components/SelectTheme'; //添加一個不存在的組件
<div className={styles.headerAction}> {/*依葫蘆畫瓢整個標簽,來切換主題*/} {/*多主題選擇*/} <SelectTheme /> {/*依葫蘆畫瓢整個標簽,來切換主題*/} {/* 多語言選擇 */} <SelectLang />
然後,照樣在“src\components”下把SelectLang文件夾拷貝更名為“SelectTheme”,然後修改"\src\components\SelectTheme\index.jsx"
import React from 'react'; import { Select } from '@alifd/next'; import { getTheme, setTheme } from '@/utils/theme'; const Option = Select.Option; const Theme_CONFIG = { '@icedesign/theme': { text: '預設主題', icon: '', }, '@alifd/theme-ice-green': { text: '綠色主題', icon: '', }, '@alifd/theme-ice-orange': { text: '橙色主題', icon: '', }, '@alifd/theme-ice-purple': { text: '紫色主題', icon: '', }, }; function changeTheme(key) { setTheme(key); } export default function SelectTheme() { const selectedTheme = getTheme(); return ( <Select onChange={changeTheme} defaultValue={selectedTheme} size="small" style={{ display: 'flex', alignItems: 'center' }} > {Object.keys(Theme_CONFIG).map((theme) => { return ( <Option value={theme} key={theme}> {Theme_CONFIG[theme].text} </Option> ); })} </Select> ); }
然後拷貝“src\utils\locale.js”改名為"theme.js"
/** * 設置當前主題 * @param {String} cTheme */ function setTheme(cTheme) { if (cTheme === undefined) { cTheme = '@icedesign/theme'; } if (getTheme() !== cTheme) { window.localStorage.setItem('theme', cTheme); // 可以在設置的主題包 @icedesign/theme 和 @alifd/theme-ice-purple 之間切換 window.__changeTheme__(cTheme); } } /** * 獲取當前主題 */ function getTheme() { if (!window.localStorage.getItem('theme')) { window.localStorage.setItem('theme', navigator.theme); } return localStorage.getItem('theme'); } export { setTheme, getTheme };
測試一下,沒問題了。總算抄出來一個功能,比較有裝逼的成就感了。
當然用iceworks的GUI還需要改一下"ice.config.js"
plugins: [ ['ice-plugin-fusion', { // 通過數組方式配置多主題包 themePackage: [{ name: '@icedesign/theme', // 設置預設載入主題,如果不進行設置,預設以最後添加主題包作為預設主題 default: true, // 設置自定義主題顏色,可以在 scss 文件中直接使用該變數,比如: .bg-color { background: $custom-color; } themeConfig: { 'custom-color': '#000',//測試自定義 }, }, { name: '@alifd/theme-ice-orange', themeConfig: { 'custom-color': '#fff', //測試自定義 }, }, { name: '@alifd/theme-ice-green', themeConfig: { 'custom-color': '#fff',//測試自定義 }, }, { name: '@alifd/theme-ice-purple', themeConfig: { 'custom-color': '#fff',//測試自定義 }, }], }], ['ice-plugin-moment-locales', { locales: ['zh-cn'], }] ],
剩下的就是用npm把這幾個主題引入到工程中了,另外fusion提供了一個可以線上編輯主題的功能,可以訪問“Fusion”
@alifd 的<Select/>組件貌似還是有一個bug,設置的defaultValue,在頁面第一次裝置的時候不會觸發onChange事件,用 window.onload 來解決,找到根目錄下的“src\index.jsx”,修改為:
import React from 'react'; import ReactDOM from 'react-dom'; import './global.scss'; // 引入基礎配置文件 import router from './router'; import LanguageProvider from './components/LocaleProvider'; import { getLocale } from './utils/locale'; const locale = getLocale(); /** * 初始進入載入預設主題 */ const loadDefaultTheme = function(){ var cTheme = window.localStorage.getItem('theme'); if (cTheme === undefined || cTheme === null) { cTheme = '@icedesign/theme'; } window.__changeTheme__(cTheme); }; const ICE_CONTAINER = document.getElementById('ice-container'); if (!ICE_CONTAINER) { throw new Error('當前頁面不存在 <div id="ice-container"></div> 節點.'); } else { window.onload= loadDefaultTheme; } ReactDOM.render( <LanguageProvider locale={locale}> {router()} </LanguageProvider>, ICE_CONTAINER );
頁面初始化進入,主題可自動引用上一次記憶的設置了。
參考材料: