美文网首页
前端(线上环境)换肤思路

前端(线上环境)换肤思路

作者: Allan要做活神仙 | 来源:发表于2019-04-25 12:47 被阅读0次

    2019-04-25-10:45:公司

    1、基础版本:

    image.png
    点击色块,切换样式表

    动态加载样式表

    缺点:换肤方案多的话实现起来就非常麻烦,拓展性不高

    2、利用CSS变量

    变量名前面要加两根连词线(--),在使用的时候只需要使用var()来访问即可

    JavaScript 操作 CSS 变量的写法如下。
    
    // 设置变量
    document.body.style.setProperty('--primary', '#7F583F');
    
    // 读取变量
    document.body.style.getPropertyValue('--primary').trim();
    // '#7F583F'
    
    // 删除变量
    document.body.style.removeProperty('--primary');
    
    

    3、antd 的 Less
    原理:全局 window 下注入 less 对象,利用 less浏览器中编译 实现换肤!

    通过 window.less.modifyVars 去动态的改变 less 变量。

    index.html

    <body>
        <link rel="stylesheet/less" type="text/css" href="static/color.less" /> //主要是这个起作用
        <script>
            window.less = {
                async: false,
                env: 'production'
            };
        </script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script>
        <noscript>
            You need to enable JavaScript to run this app.
        </noscript>
        <div id="root"></div>
    </body>
    

    使用:

    window.less
        .modifyVars(
            {
                '@primary-color': '#ee5e7b',
                '@link-color': '#ee5e7b',
                '@btn-primary-bg': 'ee5e7b',
            }
        )
        .then(() => { })
        .catch(error => {
            message.error(`Failed to update theme`);
        });
    

    window.less.modifyVars

    3、Element UI
    原理:直接替换写在 html 中的 <style></style> ,暴力替换!!!

    image.png
    1)把涉及到的颜色的css值替换成关键词,维护一个colorMap对象:
    getStyleTemplate(data) {
            const colorMap = {
              '#20a0ff': 'primary',
              '#0190fe': 'secondary',
              '#fbfdff': 'darkWhite',
              '#1f2d3d': 'baseBlack',
              '#324157': 'lightBlack',
              '#48576a': 'extraLightBlack',
              '#8391a5': 'baseSilver',
              '#97a8be': 'lightSilver',
              '#bfcbd9': 'extraLightSilver',
              '#d1dbe5': 'baseGray',
              '#e4e8f1': 'lightGray',
              '#eef1f6': 'extraLightGray',
              '#1d90e6': 'buttonActive',
              '#4db3ff': 'buttonHover',
              '#dfe6ec': 'tableBorder',
              '#d2ecff': 'datepickerInRange',
              '#afddff': 'datepickerInRangeHover',
              '#1c8de0': 'selectOptionSelected',
              '#edf7ff': 'lightBackground'
            };
            Object.keys(colorMap).forEach(key => {
              const value = colorMap[key];
              data = data.replace(new RegExp(key, 'ig'), value);
            });
            return data;
          }
    

    2)根据用户选择的主题色生成一系列对应的颜色值

    formula.json

    {
      "secondary": "color(primary s(99%) l(*0.9))",
      "darkWhite": "color(#fff blend(primary 2%))",
      "baseBlack": "color(primary h(+6) s(33%) l(18%))",
      "lightBlack": "color(baseBlack h(+5) s(27%) l(27%))",
      "extraLightBlack": "color(baseBlack h(+2) s(19%) l(35%))",
      "baseSilver": "color(baseBlack h(+3) s(16%) l(58%))",
      "lightSilver": "color(baseBlack h(+3) s(23%) l(67%))",
      "extraLightSilver": "color(baseBlack s(26%) l(80%))",
      "baseGray": "color(baseBlack s(28%) l(86%))",
      "lightGray": "color(baseBlack h(+10) s(33%) l(92%))",
      "extraLightGray": "color(baseBlack h(+6) s(33%) l(95%))",
      "buttonActive": "color(primary shade(10%))",
      "buttonHover": "color(primary tint(20%))",
      "tableBorder": "color(extraLightSilver h(-3) s(27%) l(90%))",
      "datepickerInRange": "color(primary tint(80%))",
      "datepickerInRangeHover": "color(primary tint(64%))",
      "selectOptionSelected": "color(primary shade(12%))",
      "lightBackground": "color(primary tint(92%))",
      "emptyText": "color(primary s(16%) l(44%))"
    }
    

    3)把关键词再换回刚刚生成的相应的颜色值

    import color from 'css-color-function';
    import formula from './formula.json';
    
    const generateColors = primary => {
      let colors = {};
      let baseBlack = '';
      let extraLightBlack = '';
      let extraLightSilver = '';
    
      Object.keys(formula).forEach(key => {
        const value = formula[key]
          .replace(/primary/g, primary)
          .replace(/baseBlack/g, baseBlack)
          .replace(/extraLightBlack/g, extraLightBlack)
          .replace(/extraLightSilver/g, extraLightSilver);
        colors[key] = color.convert(value);
        if (key === 'baseBlack') {
          baseBlack = colors[key];
        }
        if (key === 'extraLightBlack') {
          extraLightBlack = colors[key];
        }
        if (key === 'extraLightSilver') {
          extraLightSilver = colors[key];
        }
      });
      return colors;
    };
    
    export default generateColors;
    

    4)直接在页面上加 style 标签,把生成的样式填进去

    writeNewStyle() {
            let cssText = this.originalStyle;
            Object.keys(this.colors).forEach(key => {
              cssText = cssText.replace(new RegExp('(:|\\s+)' + key, 'g'), '$1' + this.colors[key]);
            });
    
            if (this.originalStylesheetCount === document.styleSheets.length) {
              const style = document.createElement('style');
              style.innerText = cssText;
              document.head.appendChild(style);
            } else {
              document.head.lastChild.innerText = cssText;
            }
    },
    

    总结:

    1、利用动态切换样式表
    2、暴力替换,html中插入 <Style /> 行内样式
    3、利用 Less 的变量以及在浏览器编译
    4、利用JS操作CSS变量

    相关文章

      网友评论

          本文标题:前端(线上环境)换肤思路

          本文链接:https://www.haomeiwen.com/subject/abjagqtx.html