🌓vue页面换肤实践__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
前言
最近要做一个换肤的功能,不过只是对一个页面换肤,换一下背景图呀,背景、边框、字体颜色呀之类的,并非整个项目换肤,相对比较简单,所以***以下介绍的换肤方法仅适用于页面换肤而非整个项目换肤。***
方案
查阅资料后发现有两种方案
- 为每套皮肤写一套样式,然后最外层用一个 class 充当命名空间的功能,然后将这个 class 挂到 body 上,通过切换这个 class 达到换肤的目的
- 为每套皮肤写一份配置,抽出需要换肤的样式,点击换肤时,根据配置更换样式,具体请看下面代码
此处选的是方案2,因为方案1要为每套皮肤写一套样式,我觉得方案2为每套皮肤写一套配置维护起来更容易
实现
首先把需要换肤的样式抽成一个 css 文件,命名为 default-theme.css
放到 static/theme 中,作为默认主题,引入到代码中
// 假设 header 的边框色 和 footer 的背景色 和 content 的背景图片 是需要切换的
.header {
border-color: #ffeb00;
}
.content {
background: url("/static/theme/yellow/bg.jpg");
}
.footer {
background-color: #ffeb00;
}
// main.js 引入默认主题
import '/static/theme/default-theme.css'
新建 theme.js
编写皮肤配置,以及用来匹配默认样式替换为关键字的 map 对象
// 主题配置
const theme = {
yellow: {
headerBorderColor: #ffeb00,
contentBg: '/static/theme/yellow/bg',
footerBgColor: #ffeb00
},
blue: {
headerBorderColor: #007fff,
contentBg: '/static/theme/blue/bg',
footerBgColor: #007fff
}
}
// 用 key 在默认主题中进行匹配,然后替换为 value
const themeMap = {
'#ffeb00': 'headerBorderColor',
'/static/theme/yellow/bg': 'contentBg',
'#ffeb00': 'footerBgColor'
}
export { theme, themeMap }
切换主题,分四步完成
- 首先使用 axios 获取
default-theme.css
- 替换样式为关键字:用
themeMap
的 key 值去匹配,匹配上之后替换为 value - 经过第2步
default-theme.css
中的样式就被替换成关键字了,这一步替换关键字为样式,用theme
的主题的 key 去匹配,匹配上之后替换为 value - 将处理过后的样式,写入到 style 上,再挂载到 document 上
还是看代码比较清晰
<template>
<ul>
<li @click="changeTheme('yellow')">黄色</li>
<li @click="changeTheme('blue')">蓝色</li>
</ul>
</template>
<script>
import { theme, themeMap } from 'theme.js'
export default {
methods: {
changeTheme(themeName) {
// 第一步:获取 default-theme.css
this.$axios.get('/static/theme/default-theme.css')
.then(({ data }) => {
// 第二步:替换样式为关键字
Object.keys(themeMap).forEach(key => {
const value = themeMap[key]
data = data.replace(new RegExp(key, 'ig'), value)
})
// 第三步:替换关键字为样式
const curTheme = theme[themeName]
Object.keys(curTheme).forEach(key => {
const value = curTheme[key]
data = data.replace(new RegExp(key, 'ig'), value)
})
// 第四步:将处理过的样式写到 style,再挂载到 document 上
const styleDom = document.createElement('style')
styleDom.innerText = data
styleDom.id = 'theme-style'
const oldEl = document.getElementById('theme-style')
oldEl ? document.head.replaceChild(styleDom, oldEl) : document.head.appendChild(styleDom)
})
}
}
}
</script>
参考
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 歐企鹅 原文链接:https://juejin.im/post/6869937634714583053