最近一直處於半失業狀態,好多年沒有更新對前端的理解了,閑來看看前端技術的發展。因為一直是個草台班子,身兼多職東看看西看看,一直沒太搞清楚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
);
頁面初始化進入,主題可自動引用上一次記憶的設置了。
參考材料:
