C7N主题切换

需求:

(1)多套主题随意切换

(2)一套主题下的组件有不同的样式可供切换

(3)组件之间的样式相互独立,切换互不影响

思路:

(1)将组件的样式提取出来一套模板,主题数据嵌入模板就形成了一套主题。

抽离模板,通过容器的Context 控制样式:

 

 

(1)数据与模板对接:

1.利用css辅助函数生成样式片段

例如:

// themes/Button.style.js
import {css} from 'styled-components';
export default css`
  /* 样式实现 */
`;

2.利用 styled-components 里面的 createGlobalStyle 来结合片段,生成全局样式组件

例如:

// themes/index.js
// 在这里将样式汇总,同时创建一个全局样式组件
import {createGlobalStyle} from 'styled-components';
import buttonStyle from 'Button.style.js'
import inputStyle from 'Input.style.js'
export default createGlobalStyle`
  ${buttonStyle}
  ${inputStyle}
  // ...
`;

3.全局样式组件对外提供了一个接口,用于接受外部传来的主题数据,我们只需改变传入的数据,就能实现所以组件的样式切换

4.切换主题的逻辑都在顶级容器内完成

例如:

// Container/index.js
import defaultConfig from 'path/to/config/file';
import themeOneData from 'theme-data/theme1';
import themeTwoData from 'theme-data/theme2';
const themeMap = new Map([
  ['theme1', themeOneData],
  ['theme2', themeTwoData],
]);
export default function Container(props) {
  const [config, setConfig] = useState(defaultConfig);
  const themeData = themeMap.get(config.schema);
  // 出于性能考虑,只有主题配置改变时才去重新解析数据
  const currentTheme = useMemo(() => resolveThemeData(themeData, config), config);
  return (
    <ThemeProvider value={{...theme, setTheme: setConfig}}>
      <ThemeStyle theme={currentTheme} />
      {props.children}
    </ThemeProvider>
  );
}

.

 

posted @ 2021-12-21 08:35  每天都要进步一点点  阅读(208)  评论(0编辑  收藏  举报