1.0.2 • Published 11 months ago
vue-scss-theme-plugin v1.0.2
项目介绍
用途
- 生成vue(scss)项目的多套皮肤主题css, 暂时只处理.vue和.scss的字体颜色&&背景色&&背景图
- 提供切换css方法(也可以自己写方法实现切换css)
原理
- 抽取项目文件(.vue和.scss)有主题标识"// _theme"的css属性, 生成"主题scss"代码
- 加载varsUrl指向的文件, 用该文件内的变量替换"主题scss"里的变量
- 根据配置的replace属性,替换"主题scss"内背景图路径,并按新生成的路径查找并处理图片
- 给css增加vue的命名空间(只针对提取自.vue文件且style有scoped属性的scss)
- 导出css和对应的背景图片
说明
- 需要webpack5
- 只是额外生成一些主题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>