美文网首页vue
Vue + Sass 实现简单的换肤功能

Vue + Sass 实现简单的换肤功能

作者: 南哥只想躺赢 | 来源:发表于2021-06-23 14:38 被阅读0次
前提概要

公司项目的一个需求,根据不同的域名,展示不同的主题,个人感觉这个功能很类似于网页的换肤功能。

大致想法是,先进行预设方案,然后根据不同的域名展示不同的主题,大概的思路是给html标签设置一个data-theme属性,Sass根据对应的属性值,判断使用不同的主题。

一、下载配置Scss
  1. 安装依赖
yarn add node-sass --dev
yarn add sass-loader --dev
  1. 使用scss
<style lang="scss" scoped>

</style>
二、全局引入Scss文件配置的预设主题
  1. 安装 sass-resources-loader
yarn add sass-resources-loader --dev
  1. 在 vue.config.js 文件中进行配置
chainWebpack: config => {
    const oneOfsMap = config.module.rule('scss').oneOfs.store
    oneOfsMap.forEach(item => {
      item
        .use('sass-resources-loader')
        .loader('sass-resources-loader')
        .options({
          resources: ['./src/assets/theme/themes.scss']
        })
        .end()
    })
  },

不同的版本配置方式可以参考官网
sass-resources-loader

三、不同主题实现
  1. 创建 theme.scss 文件,配置不同的配色方案
// ele和ant 只是示例
// 可以添加多种配色方案
$themes: (
  ele: (
    // 背景色
    background_main: #5242FF,
    background_deep: #3021D3,
    // 字体颜色
    font_light: #5242FF,
    font_title: #5C54FF,
    // 边框
    border_light: #5242FF,
    border_down_arrow: #5242FF,
    // 阴影
    shadow_light: #CECAFF,
    // 背景图
    background_sms: url("./../../assets/images/ele/bg_result.png"),
    image_recharge: url("./../../assets/images/ant/img_success.png"),
  ),
  ant: (
    // 背景色
    background_main: #0B6E51,
    background_deep: #094131,
    // 字体颜色
    font_light: #0B6E51,
    font_title: #0B6E51,
    // 边框
    border_light: #0B6E51,
    border_down_arrow: #0B6E51,
    // 阴影
    shadow_light: #CAFFD0,
    // 背景图
    background_sms: url("./../../assets/images/ele/bg_result.png"),
    image_recharge: url("./../../assets/images/ant/img_success.png"),
  )
);

先定义一个 map-$themes 用来存放对应的主题。

  1. 在 theme.scss 中操作 $theme 变量
// 遍历主题map
@mixin themeeach {
  @each $theme-name, $theme-map in $themes {
    $theme-map: $theme-map !global;
    // 判断html的data-theme的属性值  #{}是sass的插值表达式
    // & sass嵌套里的父容器标识   @content是混合器插槽,像vue的slot
    [data-theme="#{$theme-name}"] & {
      @content;
    }
  }
}

// 声明一个根据Key获取颜色的function
@function themed($key) {
  @return map-get($theme-map, $key);
}

// 获取背景颜色
@mixin background_color($color) {
  @include themeeach {
    background-color: themed($color)!important;
  }
}

// 获取字体颜色
@mixin font_color($color) {
  @include themeeach {
    color: themed($color) !important;
  }
}

// 获取边框颜色
@mixin border_color($color) {
  @include themeeach {
    border-color: themed($color) !important;
  }
}

// 获取向下三角形
@mixin border_down_arrow($color) {
  @include themeeach {
    border-color: transparent transparent themed($color) themed($color) !important;
  }
}

// 获取阴影颜色
@mixin shadow_light_color($color) {
  @include themeeach {
    box-shadow: 0 2px 6px 0 themed($color) !important;
  }
}

// 获取首页背景图
@mixin background_img($color) {
  @include themeeach {
    background: themed($color) center top no-repeat;
  }
}

// 获取充值成功图片
@mixin image_recharge($color) {
  @include themeeach {
    background: themed($color) center top no-repeat;
  }
}

themeeach 方法用来获取 html 的 data-theme 值
themed 根据传过来的 key 值,获取 theme.scss 中对应的颜色主题

  1. 在vue中使用
<style lang="scss" scoped>
    @import "@/style/_handle.scss";
    .header {
        font-size: 18px;
        @include font_color("font_title");
        @include background_color("background_main");
        @include border_color("border_light");
    }
</style>
  1. 换肤功能
    上面几步已经基本完成了对不同主题色的获取,项目需求是根据不同域名切换,目前就是根据域名判断后,给html标签设置不同的 data-theme 属性值。动态更换主题跟这个功能类似。
changeTheme (theme) {
  window.document.documentElement.setAttribute('data-theme', theme)
}
四、后记

这样的方式,实现简单的更换主题可以,但是如果图片过多的话,可以选择根据不同的打包命令,分别打包不同主题下的图片进行输出,这样打包完成后的静态资源会少一些,这个模块我本人还在实现中,后续补充上来。

相关文章

网友评论

    本文标题:Vue + Sass 实现简单的换肤功能

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