美文网首页
换肤方案一: scss换肤

换肤方案一: scss换肤

作者: 会飞的大象 | 来源:发表于2020-01-09 16:00 被阅读0次

    1. 效果图

    效果图

    2. 实现原理

    1. 添加全局样式,动态改变主题
    2. 通过scss 定义多套主题
    3. 使用混合模式动态取值

    3. 代码展示

    mixin.scss

    // 1.主题定义
    $theme-default: (
      font-color: red,
      font-size: 14px,
      background: pink,
    );
    
    $theme-green: (
      font-color: green,
      font-size:18px,
      background: yellow,
    );
    
    $theme-blue: (
      font-color: blue,
      font-size:24px,
      background: #fff,
    );
    
    //  2.将定义好到主题添加到map中
    $themes:(
      default:$theme-default,
      green:$theme-green,
      blue:$theme-blue,
    );
    
    // 4. 调用混合指令themify() ,定义规则,此处到规则会替换@content
    @mixin mytheme{
      @include themify() {
        color: themed("font-color");
        font-size: themed("font-size");
        .test-theme {
          background: themed("background");
        }
      }
    };
    
    // 3.定义混合指令, 切换主题,并将主题中到所有规则添加到theme-map中
    @mixin themify() {
      @each $theme-name, $map in $themes {
        // & 表示父级元素
        // !global 表示覆盖原来的
        .theme-#{$theme-name} & {
          $theme-map: () !global;
          // 循环合并键值对
          @each $key, $value in $map {
            $theme-map: map-merge($theme-map, ($key: $value)) !global;
          }
          // 表示包含 下面函数 themed()
          @content;
          $theme-map: null !global;
        }
      }
    }
    
    // 通过key获取map中到值
    @function themed($key) {
      @return map-get($theme-map, $key);
    }
    

    index.vue

    <template>
    <!-- 6. 添加全局样式 -->
      <div class="app-root" :class="themeClass">
        <div class="app-container">
          <p>{{ msg }}</p>
          <div class="test-theme">
            <span>{{ msg }}</span>
          </div>
          <select v-model="theme">
            <option value="default">Red</option>
            <option value="green">Green</option>
            <option value="blue">Blue</option>
          </select>
    
        </div>
      </div>
    </template>
    <script>
    export default {
      name: 'App',
      data() {
        return {
          msg: 'Dynamic Themes',
          theme: 'default',
          show: true
        }
      },
      computed: {
        themeClass() {
          return `theme-${this.theme}`
        }
      },
      methods: {
        handleClick: function() {
          this.show = !this.show
        }
      }
    }
    </script>
    // 5. 调用混合指令
    <style lang="scss" scoped>
    @import "@/assets/scss/mixin.scss";
    .app-container {
      @include mytheme;
    }
    
    </style>
    

    结束语

    这种方案显得有点花里胡哨,不过可以用来学习下scss
    其实直接给body动态添加一个样式
    然后定义多套样式
    这样就可以根据不同的样式名动态换肤了
    如:
    css

    .theme-1{
      color: red;
    }
    .theme-2{
      color: green;
    }
    

    给body 添加 class="theme-1",则会应用红色
    添加class="theme-2",则会应用绿色.

    相关文章

      网友评论

          本文标题:换肤方案一: scss换肤

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