1.0.2 • Published 11 months ago

vue-scss-theme-plugin v1.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
11 months ago

项目介绍

用途
  1. 生成vue(scss)项目的多套皮肤主题css, 暂时只处理.vue和.scss的字体颜色&&背景色&&背景图
  2. 提供切换css方法(也可以自己写方法实现切换css)
原理
  1. 抽取项目文件(.vue和.scss)有主题标识"// _theme"的css属性, 生成"主题scss"代码
  2. 加载varsUrl指向的文件, 用该文件内的变量替换"主题scss"里的变量
  3. 根据配置的replace属性,替换"主题scss"内背景图路径,并按新生成的路径查找并处理图片
  4. 给css增加vue的命名空间(只针对提取自.vue文件且style有scoped属性的scss)
  5. 导出css和对应的背景图片
说明
  1. 需要webpack5
  2. 只是额外生成一些主题css, 不影响项目原有打包css的流程.

安装

npm i vue-scss-theme-plugin -D
配置
const ThemePlugin = require("vue-scss-theme-plugin");
//
module.exports = {
  module: {
    rules: [
      ...,
      {
        test: /\.scss|\.vue&type=style/,
        use: [
          {
            loader: "vue-scss-theme-plugin/dist/loader",
            options: themeConfig,
          },
        ],
      },
    ],
  },
  plugins: [
    new ThemePlugin({
      // 将要生成的css文件名前缀, 默认值:"theme_"
      // fileNamePrefix: "theme_",
      // 保存主题css的文件夹(相对于webpack输出目录),默认:"themes"
      // themeCssPath: "themes",
      // 主题切换时的效果, 可选项, 以下为默认值
      transition:`border-color .2s ease-in,
                  background .2s ease-in,
                  background-color .2s ease-in,
                  color .2s ease-in;`,
      themes: {
        // default属性是必选项, 将生成theme_default.css
        "default": {
          varsUrl: "@/theme/default.scss",
        },
        // 可选项目, 将生成theme_green.css
        "green": {
          // green主题用到的变量, 默认值是 default.varsUrl.replace("default", "green")
          // varsUrl: "@/theme/green.scss",
          replace: {
            // theme_green.css内,包含该路径的背景图将被处理(替换路径,拷贝图片,增加hash)
            "assets/default/": "assets/green/",
            ...
          }
        },
        // 可选项目, 将生成theme_red.css
        "red": {
          // red主题用到的变量
          varsUrl: "@/theme/red.scss",
          replace: {
            // theme_red.css内,包含该路径的背景图将被处理(替换路径,拷贝图片,增加hash)
            "assets/default/": "assets/red/",
            ...
          }
        },
        ...
      }
    }),
    ...
  ],
};

green主题用的变量文件green.scss

$main-color: #0F0;
$text-color: #666;
...

red主题用的变量文件red.scss

$main-color: #F00;
$text-color: #333;
...

上面的配置将生成3个主题文件(theme_default.css, theme_greeen.css, theme_red.css)

生成的 theme_green.css:

.wrapper[data-v-21343943]{
    // 项目源文件里该值是$main-color, 所以xxx是green主题变量文件里的$main-color值
    color:xxx;
    // 根据green主题配置里replace属性替换图片路径, 
    // 源文件里路径是"~@/assets/default/1.png", 新路径"~@/assets/green/1.png" 
    // 按新路径查找图片, 替换css里的路径值, 并把图片输出到对应目录下
    background: url("./themes/img/1.335235.png") center 120px no-repeat,
    url("./themes/img/2.347a4a.png") center 120px no-repeat,
    url("./themes/img/3.965867.png") center 120px no-repeat;
}

.item{
    // 项目源文件里该值是$text-color, 所以xxx是green主题变量文件里的$text-color值
    color: xxx;
}

生成的 theme_red.css:

.wrapper[data-v-57879012]{
    // 项目源文件里该值是$main-color, 所以xxx是red主题变量文件里的$main-color值
    color:xxx; 
    // 根据red主题配置里replace属性替换图片路径, 
    // 源文件里路径是"~@/assets/default/1.png", 新路径"~@/assets/red/1.png" 
    // 按新路径查找图片, 替换css里的路径值, 并把图片输出到对应目录下
    background: url("./themes/img/1.3a714cae.png") center 120px no-repeat,
    url("./themes/img/2.347ac56a.png") center 120px no-repeat,
    url("./themes/img/3.9655d967.png") center 120px no-repeat;
}

.item{
    // 项目源文件里该值是$text-color, 所以xxx是red主题变量文件里的$text-color值
    color: xxx;
}

生成的 theme_default.css: 由于默认主题用到的颜色及背景图已经打包进项目的css, 所以这个css只处理transition

.wrapper[data-v-57879012],
.item{
    transition: border-color 0.2s ease-in,
                background 0.2s ease-in,
                background-color 0.2s ease-in,
                color 0.2s ease-in;
}

项目文件 "\src\views\page.vue"

<template>
    <div>1</div>
</template>
<script>
</script>
/* 源码有scoped, 生成的css属性将被添加命名空间[data-v-xxxx] */
<style lang="scss" scoped>
    // 默认导入的主题变量
    @import "@/theme/default.scss";
    .wrapper{
        width:200px;
        // _theme 将被提取到主题css里
        color:$main-color;
        // _theme 提取到主题css里,根据replace属性替换路径,依据新路径查找处理图片
        background: url("~@/assets/default/1.png") center 120px no-repeat,
        url("~@/assets/default/2.png") center 120px no-repeat,
        url("~@/assets/default/3.png") center 120px no-repeat;
    }
</style>

项目文件 "\src\theme\common.scss"

// 默认导入的主题变量
@import "@/theme/default.scss";
.item{
    width:100px;
    height:100px;
    // _theme 将被提取到主题css里, $text-color将被varsUrl文件里的变量替换
    color:$text-color;
}

切换css方法

使用插件提供的方法切换css(也可以自己实现css切换的方法)

<template>
  <div>
    <!-- 'green' 来源于配置文件属性themes的属性名-->
    <button @click="setTheme('default')">切换到default主题</button>
    <button @click="setTheme('green')">切换到green主题</button>
    <button @click="setTheme('red')">切换到red主题</button>
  </div>
</template>

<script>
// 导入配置
import themeConfig from "theme.config.js"
import Switcher from "vue-scss-theme-plugin/dist/Switcher"
const switcher = new Switcher(themeConfig)
//
export default {
  methods: {
    setTheme(theme) {
      switcher.switch(theme)
    }
  }
}
</script>