有项目需要夜间模式,就开始寻找夜间模式的解决方案。因为项目本身用的是scss,所以思路是scss切换主题。
scss依赖安装(已安装的可以略过)
- 如果是用
vite构建项目的,直接复制下面这段就好了。
shell
或者
shell
- 如果是使用
webpack构建项目的,安装下面的步骤。
- 安装依赖
1 2 3
| npm install node-sass sass-loader --save-dev 或 yarn add node-sass sass-loader -D
|
- 在
webpack配置文件中添加scss规则(在rules配置下)。
webpack.base.conf.js1 2 3 4 5
| { test: /\.scss$/, loaders: ['style', 'css', 'sass'] }
|
全局注册scss变量(有需要可以配置)
vite.config.js1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export default defineConfig({ plugins:[vue()], css: { preprocessorOptions: { scss: { additionalData: '@import "../assets/scss/globalVar.scss";@import "../assets/scss/globalMixin.scss";' } } }, })
|
- 使用
webpack构建项目的。
- 安装sass-resources-loader
1 2 3
| npm install sass-resources-loader --save-dev 或 yarn add sass-resources-loader -D
|
- 修改
build/utils.js中的 exports.cssLoaders函数。
build/utils.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| function resolveResource(name) { return path.resolve(__dirname, '../assets/scss/' + name); }
function generateSassResourceLoader() { var loaders = [ cssLoader, 'sass-loader', { loader: 'sass-resources-loader', options: { resources: [ resolveResource('globalVar.scss'), resolveResource('globalMixin.scss'), ] } } ]; if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader'].concat(loaders) } }
|
- 修改之前的return
build/utils.js1 2 3 4 5 6 7 8 9 10 11 12
| return { css: generateLoaders(), postcss: generateLoaders(), less: generateLoaders('less'), sass: generateSassResourceLoader(), scss: generateSassResourceLoader(), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') }
|
新建themes.scss(主题配置)文件,实现不同主题配色方案
./styles/themes.scss1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $themes: ( // 明亮主题 light: ( bg_color: #ffffff, font_color: #1c1c1e, border_color: rgba(0, 0, 0, 0.1) ), // 黑暗主题 dark: ( bg_color: hsla(0,0%,13%,1), font_color: #ffffff, border_color: rgba(255, 255, 255, 0.4) ) );
$--n-border-r: 4px;
|
新建handleTheme.scss文件,控制主题配色。
./styles/handleTheme.scss1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| @import "./themes.scss";
@mixin themeify { @each $theme-name, $theme-map in $themes { $theme-map: $theme-map !global; [data-theme="#{$theme-name}"] & { @content; } } }
@function themed($key) { @return map-get($theme-map, $key); }
@mixin background_color($color) { @include themeify { background-color: themed($color)!important; } }
@mixin font_color($color) { @include themeify { color: themed($color)!important; } }
@mixin border_color($color) { @include themeify { border-color: themed($color)!important; } }
|
切换主题
在app.vue或者需要用到主题切换的组件中。
app.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { onMounted, ref } from "vue";
const theme = ref(window.localStorage.getItem("theme") || "light");
onMounted(() => { window.document.documentElement.setAttribute("data-theme", theme.value); });
const changeTheme = () => { if (theme.value === "light") { theme.value = "dark"; } else { theme.value = "light"; } window.localStorage.setItem("theme", theme.value); window.document.documentElement.setAttribute("data-theme", theme.value); };
|
如何使用样式
./components/xxx.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @import "@/styles/handleTheme.scss";
.details-area, .comment-area { background-color: #FFFFFF; @include background_color("bg_color"); border-radius: $--n-border-r; }
.community-topic-title { font-weight: 700; font-size: 22px; color: #000; @include font_color("font_color"); padding-top: 0.195rem; }
|
scss 非常强大,语法也比较多,感兴趣的可以访问官网。
需要注意的是:
- 一般建议主题配置样式和其他全局样式分开写,本文中在主题配置样式文件中加入全局样式本身就是不正确的。
- 主题样式和全局样式一般建议全局注册,除非是对项目构建后的大小有要求。
感谢观看,如果对你有帮助可以关注本站,龙小亦在此谢过了