方法一:不借助less或sass预处理器的情况
我们可以使用:root选择器选取html的根元素,在根元素上定义属性被当作全局属性
:root是一个伪类,表示文档根元素,所有主流浏览器均支持 :root 选择器,除了 IE8 及更早的版本。在:root中声明相当于全局属性,只要当前页面引用了:root segment所在文件,都可以使用var()来引用。
使用方法
第一步:创建一个单独的文件color.css,专门用来存储根元素的属性,也就是全局属性
:root {
/* 背景 */
--background: white;
--gradualBackground: linear-gradient(to right bottom, #ee7752, #e73c7e, #23a6d5, #23d5ab);
--favoriteBg: #f8efd0;
/* 字体 */
--fontColor: black;
/* 边框 */
--borderColor: rgba(0, 0, 0, 0.5);
/* 边框 */
--borderHoverColor: rgba(110, 110, 110, 0.4);
/* 文章字体 */
--articleFontColor: #1f1f1f;
/* 文章灰色字体 */
--articleGreyFontColor: #616161;
/* 评论背景颜色 */
--commentContent: #F7F9FE;
/* 主题背景 */
--themeBackground: orange;
/* 主题悬停背景 */
--gradualRed: linear-gradient(to right, #ff4b2b, #ff416c);
/* 导航栏字体 */
--toolbarFont: #333333;
/* 导航栏背景 */
--toolbarBackground: rgba(255, 255, 255, 1);
/* 灰色字体 */
--greyFont: #797979;
--maxGreyFont: #595A5A;
/* footer背景 */
--gradientBG: linear-gradient(-90deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
/* 白色遮罩 */
--whiteMask: rgba(255, 255, 255, 0.3);
/* max白色遮罩 */
--maxWhiteMask: rgba(255, 255, 255, 0.5);
--maxMaxWhiteMask: rgba(255, 255, 255, 0.7);
/* mini白色遮罩 */
--miniWhiteMask: rgba(255, 255, 255, 0.15);
/* 透明 */
--transparent: rgba(0, 0, 0, 0);
/* mini黑色遮罩 */
--miniMask: rgba(0, 0, 0, 0.15);
/* 黑色遮罩 */
--mask: rgba(0, 0, 0, 0.3);
/* 半透明 */
--translucent: rgba(0, 0, 0, 0.5);
/* 深黑遮罩 */
--maxMask: rgba(0, 0, 0, 0.7);
--white: white;
--red: red;
--lightRed: #ff4b2b;
--maxLightRed: #ff416c;
--orangeRed: #EF794F;
--azure: #ECF7FE;
--blue: rgb(3, 169, 244);
--lightGray: #DDDDDD;
--maxLightGray: #EEEEEE;
--maxMaxLightGray: rgba(242, 242, 242, 0.5);
--lightGreen: #39c5bb;
--green: #67C23A;
--black: black;
--lightYellow: #F4E1C0;
--globalFont: SmileySans;
--commentURL: url(../file/comment.jpg);
--springBg: url(../file/bg1.jpg);
--admireImage: url(../file/bg1.jpg);
--toTop: url(../file/top.jpg);
--bannerWave1: url(../file/bannerwave1.png) repeat-x;
--bannerWave2: url(../file/bannerwave2.png) repeat-x;
--verifyImage: url(../file/bg1.jpg);
--toolbar: url(../file/bg.jpg);
--love: url(../file/bg.jpg);
--bg:url('https://blog-ethereal-hx.oss-cn-heyuan.aliyuncs.com/bg1.webp') no-repeat fixed;
}
第二步:将color.css引入到入口文件。比如在vue项目就引入到mian.js
import './assets/css/color.css'
第三步:在vue组件使用以及在其他.css样式文件使用
var()函数可以代替元素中任何属性中的值的任何部分。var()函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。)
<div style="background: var(--background)">
</div>
<style>
.printer {
cursor: pointer;
color: var(--white);
background: var(--translucent);
border-radius: 10px;
padding-left: 10px;
padding-right: 10px;
}
#bannerWave1 {
height: 84px;
background: var(--bannerWave1);
position: absolute;
width: 200%;
bottom: 0;
z-index: 10;
animation: gradientBG 120s linear infinite;
}
</style>
实际运用场景:黑夜白天切换
<template>
<div class="my-setting">
<div>
<!-- 太阳按钮 -->
<i
v-if="isDark"
class="el-icon-sunny"
@click="changeColor()"
></i>
<!-- 月亮按钮 -->
<i
v-else
class="fa fa-moon-o"
@click="changeColor()"
></i>
</div>
<div>
</template>
<script>
import { getCity } from "../utils/getCity"
import mousedown from '../utils/mousedown';
import { mapMutations } from 'vuex';
export default {
data () {
return {
isDark: false
}
},
mounted () {
if (this.isDaylight()) {
this.isDark = true;
let root = document.querySelector(":root");
root.style.setProperty("--background", "#272727");
root.style.setProperty("--fontColor", "white");
root.style.setProperty("--borderColor", "#4F4F4F");
root.style.setProperty("--borderHoverColor", "black");
root.style.setProperty("--articleFontColor", "#E4E4E4");
root.style.setProperty("--articleGreyFontColor", "#D4D4D4")
root.style.setProperty("--commentContent", "#D4D4D4");
root.style.setProperty("--favoriteBg", "#1e1e1e");
}
},
methods: {
// 手动切换
changeColor () {
this.isDark = !this.isDark;
let root = document.querySelector(":root");
if (this.isDark) {
root.style.setProperty("--background", "#272727");
root.style.setProperty("--fontColor", "white");
root.style.setProperty("--borderColor", "#4F4F4F");
root.style.setProperty("--borderHoverColor", "black");
root.style.setProperty("--articleFontColor", "#E4E4E4");
root.style.setProperty("--articleGreyFontColor", "#D4D4D4");
root.style.setProperty("--commentContent", "#D4D4D4");
root.style.setProperty("--favoriteBg", "#1e1e1e");
} else {
root.style.setProperty("--background", "white");
root.style.setProperty("--fontColor", "black");
root.style.setProperty("--borderColor", "rgba(0, 0, 0, 0.5)");
root.style.setProperty("--borderHoverColor", "rgba(110, 110, 110, 0.4)");
root.style.setProperty("--articleFontColor", "#1F1F1F");
root.style.setProperty("--articleGreyFontColor", "#616161");
root.style.setProperty("--commentContent", "#F7F9FE");
root.style.setProperty("--favoriteBg", "#f7f9fe");
}
},
//页面加载的完,根据时间判断白天黑夜
isDaylight () {
let currDate = new Date();
if (currDate.getHours() > 22 || currDate.getHours() < 7) {
return true;
} else {
return false;
}
},
}
}
</script>
方法二:借用less预处理器实现
借用less可以定义变量的特性来实现
想了解跟多有关less的特性可以看预处理器Less_less预处理器-CSDN博客
实际运用场景:复杂的主题设置
第一步:在src下创建theme文件夹,然后创建model.js文件,用来装各种主题对象:
这里我只定义了白天主题和夜晚主题
//model.js
// 一套白天主题以及一黑夜主题
export const themes = {
default: {
primaryColor: '#fff',
primaryTextColor: '#000'
},
dark: {
primaryColor: '#000',
primaryTextColor: '#fff'
}
}
第二步:在theme文件下创建theme.js,用来定义改变主题的方法:
import { themes } from './model'
// 修改页面中的样式变量值
const changeStyle = (obj) => {
for (const key in obj) {
document
.getElementsByTagName('body')[0]
.style.setProperty(`--${key}`, obj[key])
}
}
// 改变主题的方法
export const setTheme = (themeName) => {
const themeConfig = themes[themeName]
// 如果有主题名称,那么则采用我们定义的主题
if (themeConfig) {
changeStyle(themeConfig) // 改变样式
} else {
...
}
}
第三步:将当前主题名称themeName保存到Vuex中进行全局管理,方便所有组件使用
// 将风格
import { setTheme } from '../theme/theme'
export default new Vuex.Store({
state: {
theme: localStorage.getItem('theme') || 'default',//如果本地没有记录,就让主题默认
},
getters: {
},
mutations: {
setThemeStore (state, theme) {
setTheme(theme)
localStorage.setItem('theme', theme) // 保存主题到本地,下次进入使用该主题
},
},
actions: {},
modules: {}
})
这一步弄好了其实基本上实现了,但是以上都没有涉及到less的变量定义。为了让我们样式变得更加灵活,最好加上less预处理器,让我们的代码享受更高效的编程。
第四步:在theme文件新建style.less文件,用于定义变量
首先必须下载以下包作为加载器,因为浏览器不认识less
npm i less less-loader
然后对vue.config.js进行配置:
const { defineConfig } = require('@vue/cli-service')
const path = require('path')
module.exports = defineConfig({
transpileDependencies: true,
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [
// 加上自己的路径--任何组件中都能使用less中的变量
path.resolve(__dirname, './src/theme/style.less')
]
}
}
})
theme/style.less:
// 默认的主题颜色
@primaryColor: var(--primaryColor);
@primaryTextColor: var(--primaryTextColor);
样式中使用less变量:
<style lang="less">
.contanier {
background-color: @primaryColor;
color: @primaryTextColor;
position: relative;
width: 100wv;
}
</style>
实现主题切换:
<template>
<div id="app">
<div class="center">
<div class="switch" @click="setThemeStoreFn">
<img
src="@/assets/images/绳子.png"
alt=""
width="15px"
height="100%"
text="切换为黑暗模式"
/>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
isRouterAlive: true,
light: ''
}
},
methods: {
setThemeStoreFn () {
if (this.light === 'default') {
this.setThemeStore('dark')
this.light = 'dark'
} else {
this.setThemeStore('default')
this.light = 'default'
}
},
// 主题初始化
init () {
this.setThemeStore(this.$store.state.theme)
this.light = this.$store.state.theme
},
...mapMutations(['setThemeStore'])
},
mounted () {
this.init() // 调用初始化主题方法
},
}
</script>
以上是我用到过的主题切换方法,先总结到这里。