一、安装依赖
npm install sass sass-loader -D
npm install vue-color // 引入颜色面板
二、配置scss全局自动注入
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
css: {
loaderOptions: {
sass: {
//注意:sass-loader将文件引用写入每个组件,适合全局引入变量,但不适合在单页面应用中添加样式,如果是全局样式(非变量),建议在main.js里引入
// 路径支持别名的写法,案例就是用了路径别名,如果你没有在项目里设置,也可以自己手动设置即可
// sass-loader v10以下老版本 用的是prependData,不是additionalData
// 给 sass-loader 传递选项
// 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效
// 因为 `scss` 语法在内部也是由 sass-loader 处理的
// 但是在配置 `data` 选项的时候
// `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号
// 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置
additionalData: `@import "@/theme/style.scss";`,
},
},
},
});
三、创建主题配置
3.1 创建主题scss变量
// style.scss
// 默认的主题颜色
$primaryColor: var(--primaryColor, (123, 42, 33));
$primaryTextColor: var(--primaryTextColor, skyblue);
// 导出变量
:export {
name: "less";
primaryColor: $primaryColor;
primaryTextColor: $primaryTextColor;
}
3.2 创建主题配置文件
// model.js
// 一套默认主题以及一套暗黑主题
// 一套默认主题以及一套暗黑主题
export const themes = {
default: {
primaryColor: `${74}, ${144},${226}`,
primaryTextColor: `${74}, ${144},${226}`,
},
dark: {
primaryColor: `${0},${0},${0}`,
primaryTextColor: `${0},${0},${0}`,
},
};
3.3 创建主题切换文件
import { themes } from "./model";
// 修改页面中的样式变量值
const changeStyle = (obj) => {
for (let key in obj) {
document
.getElementsByTagName("body")[0]
.style.setProperty(`--${key}`, obj[key]);
}
};
// 改变主题的方法
export const changeTheme = (themeName) => {
themeName = themeName ? themeName : localStorage.getItem("theme") || "default";
const themeConfig = themes[themeName];
// 如果有主题名称,那么则采用我们定义的主题
if (themeConfig) {
localStorage.setItem("theme", themeName); // 保存主题到本地,下次进入使用该主题
setTheme(themeConfig);
} else {
// 采用自定义
customTheme();
}
};
// 设置主题
export const setTheme = (themeConfig) => {
localStorage.setItem("themeConfig", JSON.stringify(themeConfig)); // 保存主题色到本地
changeStyle(themeConfig); // 改变样式
};
// 自定义主题
export const customTheme = (config) => {
let themeConfig = localStorage.getItem("themeConfig")
? JSON.parse(localStorage.getItem("themeConfig"))
: {};
themeConfig = { ...themeConfig, ...config };
localStorage.setItem("theme", "custom");
setTheme(themeConfig);
};
3.4 创建vue文件,实现主题切换
<template>
<div class="hello">
<div class="box-1"></div>
<div class="box-2"></div>
<p>我是测试文字</p>
<button @click="defaultTheme">默认主题</button>
<button @click="dark">暗黑主题</button>
<button @click="custom">自定义主题</button>
<Chrome v-model="customColor" />
</div>
</template>
<script>
import { changeTheme, customTheme } from "./theme/theme";
// 引入颜色面板
import { Chrome } from "vue-color";
export default {
name: "HelloWorld",
data() {
return {
customColor: {}, // 自定义颜色面板
};
},
mounted() {
this.init(); // 初始化主题
},
methods: {
init() {
changeTheme(); // 初始化未默认主题
},
// 更改为默认主题
defaultTheme() {
changeTheme("default");
},
// 更改为暗黑主题
dark() {
changeTheme("dark");
},
// 更改为自定义主题
custom() {
// 通过颜色面板自定义颜色
const { rgba = {} } = this.customColor;
if (!rgba.a) return;
const primaryColor = `${rgba.r},${rgba.g},${rgba.b},${rgba.a}`;
customTheme({ primaryColor });
},
},
components: {
Chrome,
},
};
</script>
<style scoped lang="scss">
.hello {
display: flex;
flex-direction: column;
align-items: center;
.box-1 {
width: 50px;
height: 50px;
margin-bottom: 30px;
background: rgba($primaryColor);
}
.box-2 {
width: 50px;
height: 50px;
margin-bottom: 30px;
background: rgba($primaryTextColor);
}
p {
color: $primaryTextColor;
}
}
</style>
参考