介绍
Nuxt.js
项目,设计了几种主题。点击选择的主题,页面样式对应切换
项目样式使用less
编写
思路
- 通过给
body
添加不同类名的方法,来切换。 - 各个主题对应的颜色,配置在一个
less
文件中 less
文件中定义一个方法,该方法可以循环生成所有的样式- 各组件的样式部分,使用此方法生成所有主题的样式
实现
以两种主题theme-green
和theme-red
为例
- 在
assets/less/
目录下添加theme.less
文件
@themes: theme-green, theme-red;
@theme-green-mc: #4AD991;
@theme-red-mc: red;
.setTheme() {
.loop(@i) when (@i < length(@themes)+1){
@theme: extract(@themes, @i);
@mc: '@{theme}-mc';
body.@{theme}{
.theme(@@mc);
}
.loop(@i+1);
}
.loop(1);
}
- 组件中样式部分代码如下
@import '../../assets/less/theme.less';
.theme(@mc) {
.gbanner{
position: relative;
height: 564px;
// ...
.gbanner-d{
color: @mc;
// ...
}
}
// ...
}
.setTheme();
- 修改
nuxt.config.js
文件,给body
添加默认类theme-green
// ...
module.exports = {
// ...
head: {
// ...
bodyAttrs: {
class: 'theme-green'
}
},
// ...
}
- 切换主题部分代码
// ...
export default {
// ...
methods: {
// ...
changeTheme(theme) {
document.body.setAttribute('class', theme)
}
// ...
}
// ...
}
// ...
持久化
- 持久化的话,需要将
theme
值存储到localstorage
或者cookie
中- 页面初始化时,给
body
设置类名的方法暂时没有找到- 用
插件
的方式或者在beforeMount
或者mounted
生命周期设置的话,页面刚加载的时候还是默认主题,然后突然变成设置的主题。效果不好- 这里换一下思路,给全部的
layout
最外层div
设置类名- 这里还是以两种主题
theme-green
和theme-red
为例
- 在
assets/less/
目录下添加theme.less
文件
@themes: theme-green, theme-red;
@theme-green-mc: #4AD991;
@theme-red-mc: red;
.setTheme() {
.loop(@i) when (@i < length(@themes)+1){
@theme: extract(@themes, @i);
@mc: '@{theme}-mc';
// 这里有区别,body后面有一个空格
body .@{theme}{
.theme(@@mc);
}
.loop(@i+1);
}
.loop(1);
}
- 组件中样式部分代码不变。如下
@import '../../assets/less/theme.less';
.theme(@mc) {
.gbanner{
position: relative;
height: 564px;
// ...
.gbanner-d{
color: @mc;
// ...
}
}
// ...
}
.setTheme();
- 修改
nuxt.config.js
文件,去掉添加的bodyAttrs
// ...
module.exports = {
// ...
head: {
// ...
// bodyAttrs: {
// class: 'theme-green'
// }
},
// ...
}
- 修改
store/index.js
文件,添加主题相关代码(nuxtServerInit
相关设置参考:Nuxt.js常见问题)
// ...
import Cookies from 'js-cookie'
// ...
export const state = () => ({
themes: ['theme-green', 'theme-red'],
theme: 'theme-green',
// ...
})
// ...
export const mutations = {
setTheme(state, theme) {
if (state.themes.includes(theme)) {
state.theme = theme
Cookies.set('theme', theme)
}
},
// ...
}
export const actions = {
nuxtServerInit({ commit }, { req }) {
const cookie = req && req.headers.cookie
if (cookie) {
// 将cookie转成json对象(自己实现该方法)
const cookieObj = cookieParse(cookie)
const { theme } = cookieObj
theme && commit('setTheme', theme)
}
},
// ...
}
// ...
- 修改
store/getters.js
文件
const getters = {
theme: state => state.theme,
// ...
}
// ...
- 在根目录下新建
mixins/
目录 - 在
mixins/
目录下新建layout.js
文件(除error.vue
外的所有layout
文件都mixin
此文件)
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['theme'])
},
created() {
if (process.browser) {
this.$store.commit('setTheme', this.theme)
}
}
}
- 修改除
error.vue
外的所有layout
文件
<template>
<div class="layout-container" :class="theme">
<!-- 省略内容 -->
</div>
</template>
<script>
import layoutMixin from '@/mixins/layout'
export default {
mixins: [layoutMixin],
// ...
}
</script>
- 切换主题部分代码
// ...
export default {
// ...
methods: {
// ...
changeTheme(theme) {
this.$store.commit('setTheme', theme)
}
// ...
}
// ...
}
// ...
发表评论