勤浪

The simple things are always hard!

 

使用ice-plugin-fusion给icedesign的模板加个主题(theme)

最近一直处于半失业状态,好多年没有更新对前端的理解了,闲来看看前端技术的发展。因为一直是个草台班子,身兼多职东看看西看看,一直没太搞清楚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
);  

页面初始化进入,主题可自动引用上一次记忆的设置了。

 

参考材料:

ice-plugin-fusion

ICE主题配置

Select选择器

 

posted on 2019-09-18 14:57  勤浪  阅读(1187)  评论(0编辑  收藏  举报

导航