前提提要:有黑白两种皮肤,需要动态换肤
方案一:引入less.js,浏览器上动态编译。
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>less换肤</title>
<link rel="stylesheet/less" type="text/css" href="./index.less" />
<script src="https://cdn.bootcdn.net/ajax/libs/less.js/4.1.1/less.min.js"></script>
<script>
let whiteVars = {
'@body-bgColor': '#fff',
'@text-color': '#000',
'@btn-color': '#fff',
'@primary-color': '#1890ff'
}
let blackVars = {
'@body-bgColor': '#000',
'@text-color': '#fff',
'@btn-color': '#fff',
'@primary-color': '#1890ff'
};
// 根据传入的变量,编译生成新的css,把这些css用style标签包裹起来,插入到对应的less文件下,见下方:图一
window.less.modifyVars(whiteVars);
</script>
</head>
<body>
<h1>less换肤方案</h1>
<button class="btn" onclick="window.less.modifyVars(whiteVars);">白色皮肤</button>
<button class="btn" onclick="window.less.modifyVars(blackVars);">黑色皮肤</button>
</body>
</html>
- index.less
@body-bgColor: #fff;
@text-color: #000;
@btn-color: #fff;
@primary-color: #1890ff;
body{
background: @body-bgColor;
color: @text-color;
}
.btn{
color: @btn-color;
border-color: @primary-color;
background: @primary-color;
}

方案二:改变最外层的容器的class
因为要node服务编译less,所以这里采用 vue-cli框架
- main.js
import Vue from 'vue'
import App from './App.vue'
import './assets/styles/white.less'
import './assets/styles/black.less'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
- index.less
*{
padding: 0;
margin: 0;
}
html,body,.application{
height: 100%;
}
.theme-@{skin} {
&.application{
background: @body-bgColor;
color: @text-color;
}
.btn{
color: @btn-color;
border-color: @primary-color;
background: @primary-color;
}
}
- white.less
@body-bgColor: #fff;
@text-color: #000;
@btn-color: #fff;
@primary-color: #1890ff;
@skin: light;
@import './index.less';
- black.less
@body-bgColor: #000;
@text-color: #fff;
@btn-color: #fff;
@primary-color: #1890ff;
@skin: dark;
@import './index.less';
- app.vue (这里是触发换肤的地方,改变最外层的容器的class)
<template>
<div id="app" :class="['application', drak?'theme-dark':'theme-light']">
<h1>less换肤方案2</h1>
<button class="btn" @click="drak=false">白色皮肤</button>
<button class="btn" @click="drak=true">黑色皮肤</button>
</div>
</template>
<script>
export default {
data() {
return {
drak: false
}
}
}
</script>
方案三:移动css文件位置 或者 禁用css文件
先看图二,理解下这个方案是怎么实现的

这里涉及自动化工程,还是采用 vue-cli
- webpack.base.conf.js
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js',
black: './src/assets/styles/black.less',
white: './src/assets/styles/white.less',
},
...
}
- black.less
@body-bgColor: #000;
@text-color: #fff;
@btn-color: #fff;
@primary-color: #1890ff;
@import './index.less';
- white.less
@body-bgColor: #fff;
@text-color: #000;
@btn-color: #fff;
@primary-color: #1890ff;
@import './index.less';
- index.less
body{
background: @body-bgColor;
color: @text-color;
}
.btn{
color: @btn-color;
border-color: @primary-color;
background: @primary-color;
}
- app.vue (这里是触发换肤的地方,禁用css文件)
<template>
<div id="app">
<h1>less换肤方案3</h1>
<button class="btn" @click="setBlackTheme(false)">白色皮肤</button>
<button class="btn" @click="setBlackTheme(true)">黑色皮肤</button>
</div>
</template>
<script>
export default {
methods: {
setBlackTheme(flag) {
document.querySelectorAll('link').forEach(tag => {
let tagName = tag.href.split('/').pop();
if (tagName.startsWith('white')) {
if (flag) {
tag.setAttribute('disabled', 'disabled');
} else {
tag.removeAttribute('disabled');
}
}
})
}
}
}
</script>
总结,所有的方案,都是css样式覆盖实现的。
当然以上只是一些简单的总结,实际项目中更复杂,需要解决一些其他的问题,为方便理解,在这里没有写上去。项目中如有疑问,欢迎留言讨论。
网友评论