暗黑模式切换(vue版)
网上很多方法都采用scss,现在用原生css实现一种简单版mode.vue(随便定义名称):// 在data里面定义mode为false/** 模式切换* */fnChangeMode(){this.mode = !this.mode;if (this.mode == true) {window.document.documentElement.setAttribute('data-theme',
·
网上很多方法都采用scss,现在用原生css实现一种简单版
mode.vue(随便定义名称):
// 在data里面定义mode为false
/*
* 模式切换
* */
fnChangeMode(){
this.mode = !this.mode;
if (this.mode == true) {
window.document.documentElement.setAttribute('data-theme', 'dark')
} else {
window.document.documentElement.setAttribute('data-theme', 'light')
}
}
/**
注意这里的css样式必须使用全局,不能加scoped标签!!!
**/
<style>
:root[data-theme=dark] {
/* 模式切换变量,默认light模式 */
--current-background-color: var(--dark-background-color);
--current-primary-color: var(--dark-primary-color);
/* 深色主题 */
--dark-primary-color: #fff;
--dark-background-color: #282c34;
}
:root[data-theme=light] {
/* 模式切换变量,默认light模式 */
--current-background-color: var(--light-background-color);
--current-primary-color: var(--light-primary-color);
/* 浅色主题 */
--light-primary-color: #666;
--light-background-color: #fff;
}
.header-wrap {
height: 60px;
background-color: var(--current-background-color);
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
}
.mode{
margin-right: 20px;
cursor: pointer;
color:var(--current-primary-color)!important;
}
</style>
升级版(支持ie)
app.vue
#app {
background: var(--fill-1);
}
utils/theme.js
import { lightTheme, darkTheme } from '../less/variable';
import cssVars from 'css-vars-ponyfill';
export const initTheme = theme => {
document.documentElement.setAttribute('data-theme', theme);
cssVars({
watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用
variables: theme == 'dark' ? darkTheme : lightTheme, // variables 自定义属性名/值对的集合
onlyLegacy: false, // false 默认将css变量编译为浏览器识别的css样式 true 当浏览器不支持css变量的时候将css变量编译为识别的css
});
};
variable.js
//浅色
export const lightTheme = {
'--fill-1': '#fff',
'--text': '#3c3c3c',
'--slide-arrow': '#000000',
};
// 深色
export const darkTheme = {
'--fill-1': '#222',
'--text': '#fff',
'--slide-arrow': '#f2f2f2',
'--text-1': 'rgba(255, 255, 255, 0.3)',
'--text-2': '#ffcd32',
};
header.vue(随便定义,作用用于切换样式)
import { initTheme } from '@/utils/theme';
export default {
name: 'Header',
data() {
return {
theme: 'dark',
};
},
methods: {
changeTheme() {
this.theme == 'light' ? (this.theme = 'dark') : (this.theme = 'light');
initTheme(this.theme);
},
},
created() {
initTheme(this.theme);
},
};
方案2(一行代码实现)
html {
filter: invert(1) hue-rotate(180deg);
}
本次的暗黑模式使用到两个滤镜函数:invert()、hue-rotate()。
invert():反相,反向输出图像着色,值为0%则无变化,值为0~100%则是线性乘子效果,值为100%则完全反转
hue-rotate():色相旋转,减弱图像着色,处理非黑白的颜色,值为0deg则无变化,值为0~360deg则逐渐减弱,值超过360deg则相当绕N圈再计算剩余的值
invert()简单理解就是黑变白,白变黑,黑白颠倒。hue-rotate()简单理解就是冲淡颜色。为了确保主题色调不会改变,将色相旋转声明为180deg比较合理。
按照设计原则来说,换肤只针对组件,像一些媒体类型的元素,例如背景、图片、视频等,都是不能直接处理的,需保持其原样。既然暗黑模式是使用了滤镜的反相和色相旋转实现,那么对这些媒体元素再次使用滤镜的反相和色相旋转就能复原了。
img,
video {
filter: invert(1) hue-rotate(180deg);
}
整体代码
<body>
<input class="ios-switch" type="checkbox">
<div class="main">网站主体</div>
</body>
.ios-switch {
...
&:checked {
...
& + .main {
filter: invert(1) hue-rotate(180deg);
img,
video,
.exclude {
filter: invert(1) hue-rotate(180deg);
}
}
}
}
.main {
background-color: #fff;
transition: all 300ms;
}
方案3(element切换)
更多推荐
已为社区贡献4条内容
所有评论(0)