vue 实现换肤
实现 Vue 换肤功能的常见方法
使用 CSS 变量动态切换主题色
通过 CSS 变量定义主题色,结合 Vue 动态修改根元素的变量值实现换肤。在 src/assets/styles 下创建全局样式文件:
:root {
--primary-color: #409EFF;
--background-color: #f5f7fa;
}
.dark-theme {
--primary-color: #304156;
--background-color: #1c2b36;
}
在 Vue 组件中通过 document.documentElement.className 切换类名:
methods: {
toggleTheme() {
const htmlEl = document.documentElement
htmlEl.className = htmlEl.className === 'dark-theme' ? '' : 'dark-theme'
}
}
基于 SCSS 变量和 webpack 动态编译
创建 src/styles/theme.scss 定义主题变量:
$themes: (
light: (
primary: #409EFF,
background: #f5f7fa
),
dark: (
primary: #304156,
background: #1c2b36
)
);
通过 sass-resources-loader 动态注入变量,在 vue.config.js 中配置:
module.exports = {
chainWebpack: config => {
const oneOfsMap = config.module.rule('scss').oneOfs.store
oneOfsMap.forEach(item => {
item.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: './src/styles/theme.scss'
})
})
}
}
使用 Vuex 管理主题状态
在 store 中维护当前主题状态:
const store = new Vuex.Store({
state: {
theme: 'light'
},
mutations: {
setTheme(state, theme) {
state.theme = theme
}
}
})
组件内通过计算属性绑定样式:
computed: {
themeClass() {
return `${this.$store.state.theme}-theme`
}
}
动态加载外部样式文件
准备不同主题的 CSS 文件(如 theme-light.css 和 theme-dark.css),通过动态创建 link 标签切换:
function loadTheme(themeName) {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = `/static/css/theme-${themeName}.css`
document.head.appendChild(link)
// 移除旧主题
const oldLinks = document.querySelectorAll('link[rel="stylesheet"][href^="/static/css/theme-"]')
oldLinks.forEach(link => {
if (link.href !== `/static/css/theme-${themeName}.css`) {
link.remove()
}
})
}
结合 Element UI 的主题切换
使用 Element UI 官方主题工具生成不同主题 CSS,通过动态修改 document.body.className 实现:
import '../assets/theme-light/index.css'
import '../assets/theme-dark/index.css'
export default {
methods: {
changeTheme(theme) {
document.body.className = `el-theme-${theme}`
}
}
}
持久化存储主题选择
使用 localStorage 保存用户选择的主题,在应用初始化时读取:
created() {
const savedTheme = localStorage.getItem('app-theme') || 'light'
this.$store.commit('setTheme', savedTheme)
},
methods: {
toggleTheme() {
const newTheme = this.$store.state.theme === 'light' ? 'dark' : 'light'
this.$store.commit('setTheme', newTheme)
localStorage.setItem('app-theme', newTheme)
}
}
每种方法各有优劣,CSS 变量方案适合简单场景,SCSS 方案适合复杂主题系统,外部样式文件方式适合完全独立的主题样式。根据项目需求选择合适方案或组合使用。







