1. 效果图
效果图2. 实现原理
- 添加全局样式,动态改变主题
- 通过scss 定义多套主题
- 使用混合模式动态取值
3. 代码展示
mixin.scss
// 1.主题定义
$theme-default: (
font-color: red,
font-size: 14px,
background: pink,
);
$theme-green: (
font-color: green,
font-size:18px,
background: yellow,
);
$theme-blue: (
font-color: blue,
font-size:24px,
background: #fff,
);
// 2.将定义好到主题添加到map中
$themes:(
default:$theme-default,
green:$theme-green,
blue:$theme-blue,
);
// 4. 调用混合指令themify() ,定义规则,此处到规则会替换@content
@mixin mytheme{
@include themify() {
color: themed("font-color");
font-size: themed("font-size");
.test-theme {
background: themed("background");
}
}
};
// 3.定义混合指令, 切换主题,并将主题中到所有规则添加到theme-map中
@mixin themify() {
@each $theme-name, $map in $themes {
// & 表示父级元素
// !global 表示覆盖原来的
.theme-#{$theme-name} & {
$theme-map: () !global;
// 循环合并键值对
@each $key, $value in $map {
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
// 表示包含 下面函数 themed()
@content;
$theme-map: null !global;
}
}
}
// 通过key获取map中到值
@function themed($key) {
@return map-get($theme-map, $key);
}
index.vue
<template>
<!-- 6. 添加全局样式 -->
<div class="app-root" :class="themeClass">
<div class="app-container">
<p>{{ msg }}</p>
<div class="test-theme">
<span>{{ msg }}</span>
</div>
<select v-model="theme">
<option value="default">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
msg: 'Dynamic Themes',
theme: 'default',
show: true
}
},
computed: {
themeClass() {
return `theme-${this.theme}`
}
},
methods: {
handleClick: function() {
this.show = !this.show
}
}
}
</script>
// 5. 调用混合指令
<style lang="scss" scoped>
@import "@/assets/scss/mixin.scss";
.app-container {
@include mytheme;
}
</style>
结束语
这种方案显得有点花里胡哨,不过可以用来学习下scss
其实直接给body动态添加一个样式
然后定义多套样式
这样就可以根据不同的样式名动态换肤了
如:
css
.theme-1{
color: red;
}
.theme-2{
color: green;
}
给body 添加 class="theme-1",则会应用红色
添加class="theme-2",则会应用绿色.
网友评论