假如要使用两套主题:蓝色、红色
例如:
首先确保自己的vue3项目有less,这边不多做接入解释
1、在src目录下建一个styles文件夹,在syles文件夹下面新建两个less文件:theme.less和variables.less;
theme.less的样式代码(默认的主题色):
@import './variables.less';:root {--primary-color: #e83d23; // 默认主题颜色
}
variables.less的样式代码(供切换的主题,可以制作多种,我这边只做两种):
.red-theme {--primary-color: #e83d23;
}.blue-theme {--primary-color: #4c7bec;
}
2、使用vuex来管理,这边vuex怎么接入就不过多叙述,请先接入vuex;然后直接粘贴我里面的全部代码
store下面的index代码:
import { createStore } from 'vuex'// 持久化的插件
import createPersistedState from "vuex-persistedstate"const state = {// 当前的主题currentTheme: 'red-theme',
}
const getters = {
}
const mutations = {// 切换主题的方法switchTheme(state, theme) {state.currentTheme = theme;},
}
const actions = {// 异步切换主题switchTheme({ commit }, theme) {commit('switchTheme', theme);},
}const modules = {}export default createStore({state,mutations,actions,getters,modules,plugins: [createPersistedState()],
})
3、在App.vue里面的顶层div使用我当前的样式class,这边直接粘贴代码:
App.vue:
<template><div :class="currentTheme"><router-view v-slot="{ Component }"><keep-alive><component :is="Component" v-if="$route.meta.keepAlive" /></keep-alive><component :is="Component" v-if="!$route.meta.keepAlive" /></router-view></div>
</template><script lang="ts">import { defineComponent } from 'vue'import { mapState } from 'vuex'export default defineComponent({name: 'App',components: {},computed: {...mapState(['currentTheme']),}})
</script>
主要代码是最外层div上面绑定的class,下面的router-view你们项目是怎样的就是怎样的,不用和我的一样,然后再是下面的计算属性,引入vuex里面的主题变量
4、在页面代码里面使用切换功能,就可以切换了,例如:
index.vue:
<template><div><button @click="switchTheme('red-theme')">点击切换为红色</button><button @click="switchTheme('blue-theme')">点击切换为蓝色</button><div class="test">测试切换主题</div></div>
</template><script setup>import { ref } from 'vue';import { useStore } from 'vuex'const store = useStore()const currentTheme = ref('red-theme');const switchTheme = (theme) => {store.commit('switchTheme', theme)}
</script>
<style lang="less" scoped>.test {// 使用第一步定义的样式变量color: var(--primary-color);}
</style>
至此就可以了,其实思路很简单:就是在根目录上面绑定样式,通过切换这个样式来做到主题的切换,如果使用的主题量很大,是不是就得考虑性能问题了...