实现主题切换的方案调研

149 阅读4分钟

1.通过不同配置文件实现

定义样式配置文件,动态挂载到:root下,项目中所有样式开发时,使用配置文件中定义的变量,适用于少量主题,如黑白两种主题等,只需要定义两套动态挂载。

优点:简单,只需要前端负责人和ui进行沟通进行配置项的定义和改动,开发人员****正常开发就行了,

缺点:缺点扩展性不好不支持自定义,少量主题适用

挂载:

export function insertThemeStyle(options: ThemeInfoType) {
  const tplStr = ':root{<content>}';
  const attrArr = Object.values(options.vars).flat();
  style.innerHTML = tplStr.replace(
    '<content>',
    attrArr.reduce((a, b) => {
      const [key, value] = b.split(':');
      return a + `--${key}:${value};\n`;
    }, ''),
  );
  if (!isInit) {
    isInit = true;
    document.head.appendChild(style);
  }
}

配置示例:theme.info.json

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "100010000076",
    "describe": "羚知风格",
    "content": {
      "vars": {
        "global": [
          "primary:#2BBFC7",
          "primary-light:rgba(59,189,248,1)",
          "primary-dark:rgba(14,110,232,1)",
          "danger:rgba(222,0,0,1)",
          "danger-light:rgba(255,64,64,1)",
          "danger-dark:rgba(163,1,1,1)",
          "success:rgba(5,198,13,1)",
          "success-light:rgba(7,203,45,1)",
          "success-dark:rgba(1,146,27,1)",
          "link:rgba(22,134,229,1)",
          "fs:14px",
          "fs-small:12px",
          "fs-large:14px",
          "icon:rgba(98,112,139,1)",
          "disabled:rgba(153,153,153,1)",
          "bd-color:#dbe1ea",
          "color:rgba(0,0,0,1)",
          "color-dark:#000000",
          "color-light:rgba(102,102,102,1)",
          "sider-size:330px"
        ],
        "header": ["app-header-color:#2E3F4F", "app-header-bg:#ffffff"],
        "nav": [
          "nav-height:80px",
          "nav-bg:rgba(18,122,255,1)",
          "nav-sub-bg:rgba(255,255,255,1)",
          "nav-sub-bg2:rgba(241,244,247,0.8)",
          "nav-item-bg-selected:#2BBFC7",
          "nav-item-color:#2E3F4F",
          "nav-item-bg:#F4F4F4",
          "nav-item-color-selected:rgba(255,255,255,1)",
          "nav-sub-item-bg-selected:#F3F5F6",
          "nav-sub-item-color-selected:#2BBFC7",
          "nav-sub-item-color:rgba(55,66,105,1)",
          "nav-bd-color:rgba(18,122,255,1)"
        ],
        "tabbar": [
          "tab-height:48px",
          "tab-bg:#dbe1ea",
          "tab-item-bg:#e7ecf2",
          "tab-item-height:32px",
          "tab-item-color:rgba(72,83,108,1)",
          "tab-item-selected-bg:#f3f6f9",
          "tab-item-selected-color:rgba(18,122,255,1)"
        ],
        "table": ["table-bg:#ffffff", "table-head-bg:rgba(219,225,234,1)", "table-bd:rgba(245,245,245,1)", "table-row-hover-color:rgba(237,245,250,1)"],
        "drawer": [
          "drawer-title-height:48px",
          "drawer-title-bg:rgba(255,255,255,1)",
          "drawer-divider-color:rgba(219,225,234,1)",
          "drawer-footer-height:44px",
          "drawer-footer-bg:rgba(255,255,255,1)",
          "drawer-content-bg:rgba(243,246,249,1)"
        ],
        "modal": [
          "modal-title-height:44px",
          "modal-title-bg:#ffffff",
          "modal-divider-color:rgba(219,225,234,1)",
          "modal-footer-height:44px",
          "modal-footer-bg:rgba(243,246,249,1)",
          "modal-content-bg:rgba(243,246,249,1)"
        ],
        "card": [
          "card-image-radius:4px",
          "card-image-bg:rgba(219,225,234,1)",
          "card-radius:4px",
          "card-content-bg:rgba(255,255,255,1)",
          "card-shadow:0 0 4px 0 rgba(0,0,0,0.2)",
          "card-bd-color:rgba(219,225,234,1)",
          "card-hover-bd-color:rgba(18,122,255,1)",
          "card-footer-bg:rgba(219,225,234,1)"
        ],
        "contentLayout": [
          "content-box-bg:#ffffff",
          "content-two-column-box-left-bg:rgba(255,255,255,1)",
          "content-two-column-box-right-bg:#f0f2f5",
          "content-two-column-box-color:rgba(51,51,51,1)",
          "content-info-box-bg:rgba(255,255,255,1)",
          "content-info-box-bd-color:#dbe1ea",
          "content-info-box-title-bg:rgba(0,0,0,0)",
          "content-info-box-title-bd:rgba(0,0,0,0)",
          "content-info-box-title-height:40px",
          "content-list-box-bg:rgba(255,255,255,1)",
          "content-list-box-bd-color:rgba(219,225,234,1)",
          "content-list-box-title-bg:rgba(229,235,241,1)",
          "content-list-box-title-bd:rgba(219,225,234,1)",
          "content-list-box-title-height:40px",
          "content-tools-box-bg:rgba(255,255,255,1)"
        ],
        "form": [
          "form-redius:0px",
          "form-bg:rgba(255,255,255,1)",
          "form-bd:rgba(181,190,207,1)",
          "form-bg-dark:rgba(240,244,245,1)",
          "form-bg-light:rgba(217,223,229,1)",
          "form-divider-color:rgba(219,225,234,1)"
        ],
        "scrollbar": [
          "scrollbar-width:8px",
          "scrollbar-track-bg:rgba(239,241,244,1)",
          "scrollbar-thumb-bg:rgba(185,193,203,1)",
          "scrollbar-thumb-hover-bg:rgba(195,209,229,1)",
          "scrollbar-track-shadow:0 0 3px 0 rgba(255, 255, 255, 0.1) inset",
          "scrollbar-thumb-shadow:0 0 3px 0 rgba(0, 0, 0, 0.3) inset"
        ],
        "relation": [
          "force-place:rgba(255,187,34,1)",
          "force-device:rgba(185,181,255,1)",
          "force-person:rgba(34,153,255,1)",
          "force-nonVehicle:rgba(255,131,125,1)",
          "force-vehicle:rgba(20,204,143,1)"
        ]
      },
      "style": {
        "menuType": "horizontal",
        "hasTab": true
      }
    },
    "type": "theme"
  }
}

2.通过选择主色副色等必要颜色通过算法生成一套色系

适用antd中定制主题,通过选择主色副色,以及指定预设算法,生成对应的主题配置,传入渲染