赞
踩
首先我们需要思考一个问题:后台管理系统一键换肤换的是哪些颜色?
虽然我们用了element UI的menu菜单组件,但是他默认可能就只有两种主题色,可能我们还需要其他的颜色,或者说一些表现更细粒度的颜色体现,细节更多,所以需要修改组件里面的一些颜色。
theme.scss
html[data-theme="red"] { // 菜单主题色 .el-layouts-sider-light { background-color: #29343f; } .el-menus-light { background-color: #29343f; .el-submenus .el-menus { background-color: #29343f; } .el-menus-item-link { color: #CACFDC; background-color: #29343f; &:hover { background-color: #3d4d5d; } } } }
这里只列举了一套背景色为red情况下菜单里面的各种颜色,还有其他颜色,你应该要知道。
可以看到,当html标签上的data-theme="red"的时候,就回去运用里面的样式,所以思路就是选择主题色的时候需要动态修改html上的data-theme属性
document.documentElement.dataset.theme = selectTheme.fileName;
自己写的一些样式,可以通过css变量的方式去控制,css变量的作用和用法这边不做赘述,具体可以百度查看,具体思路: 选择主题的时候动态给html标签添加style样式定义css变量
const vars = Object.keys(selectTheme.colors).map(key => `--${key.slice(1)}:${selectTheme.colors[key]}`).join(';');
document.documentElement.setAttribute('style', vars);
浏览器编译出来如下图:
现在就定义好了css变量,然后在代码中直接可以使用了
var.css
// 自定义变量
$body-bg: #f0f6fa;
$primary-color: var(--primary-color, #1990ff);
$primary-color-hover: var(--primary-color-hover, #42aaff);
$bg: var(--dark-theme-color, #32394d);
因为使用sass预编译写的,用了sass变量的方式来引用,在代码中直接 sass变量 $primary-color,注意这里我们需要在vue.config.js中做个配置,才可直接使用sass变量
vue.config.js
css: {
loaderOptions: {
sass: {
prependData: '@import "~@portal/common/lib/theme/vars.scss";'
}
}
},
首先预先生产几套对应的css文件,放在public文件夹下,具体怎么生成,可查阅element UI的官网
然后切换的时候再动态的去引入对应的css文件
const themeLink = document.querySelector('link[rel=stylesheet][theme]');
if (themeLink && themeLink.href.indexOf(selectTheme.fileName) === -1) {
themeLink.href = themeLink.href.replace(/(\w)+\.css/, selectTheme.fileName + '.css');
}
为了提高样式文件的加载速度,可以采用
预加载:
页面资源预加载(Link prefetch)是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个Web页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。
入口文件index.html
<link href="<%= BASE_URL %>static/theme/default.css" rel=stylesheet theme>
<link href="<%= BASE_URL %>static/theme/blue.css" rel=prefetch as=style>
<link href="<%= BASE_URL %>static/theme/red.css" rel=prefetch as=style>
<link href="<%= BASE_URL %>static/theme/green.css" rel=prefetch as=style>
<link href="<%= BASE_URL %>static/theme/purple.css" rel=prefetch as=style>
浏览器控制台查看请求可以看到
vuex moudle theme.js
// initial state import themeConfig from '@portal/common/lib/theme/config.js'; const state = { themeConfig, currentTheme: null }; const getters = { currentTheme (state) { return state.currentTheme; }, themeConfig (state) { return state.themeConfig; } }; const actions = { initTheme (context) { const { commit, rootState, getters } = context; let themeInfo = JSON.parse(localStorage.getItem(`${rootState.auth.userInfo.LoginEmail}-theme`) || null); if (!themeInfo || !getters.themeConfig.find(item => item.name === themeInfo.name)) { themeInfo = { user: rootState.auth.userInfo.LoginEmail, name: 'default' }; } commit('setCurrentTheme', themeInfo); }, changeTheme (context, themeName) { const themeItem = state.themeConfig.find(item => item.name === themeName); const { commit, getters, rootState } = context; if (themeItem.name !== getters.currentTheme) { commit('setCurrentTheme', { user: rootState.auth.userInfo.LoginEmail, name: themeItem.name }); } } }; const mutations = { setCurrentTheme(state, themeInfo) { // todo 后边换成document.head const selectTheme = state.themeConfig.find(item => item.name === themeInfo.name); const themeLink = document.querySelector('link[rel=stylesheet][theme]'); if (themeLink && themeLink.href.indexOf(selectTheme.fileName) === -1) { themeLink.href = themeLink.href.replace(/(\w)+\.css/, selectTheme.fileName + '.css'); } const vars = Object.keys(selectTheme.colors).map(key => `--${key.slice(1)}:${selectTheme.colors[key]}`).join(';'); document.documentElement.setAttribute('style', vars); document.documentElement.dataset.theme = selectTheme.fileName; localStorage.setItem(`${themeInfo.user}-theme`, JSON.stringify(themeInfo)); state.currentTheme = themeInfo.name; } }; export default { namespaced: true, state, getters, actions, mutations };
config.js
export default [ { name: 'blue', showName: '深邃蓝', fileName: 'blue', colors: { '$primary-color': '#4975FF', '$primary-color-hover': '#7299ff;', '$light-theme-color': '#3d4760', '$dark-theme-color': '#0A1431', } }, { name: 'default', showName: '默认主题', fileName: 'default', colors: { '$primary-color': '#0068FE', '$primary-color-hover': '#2988ff', '$light-theme-color': '#fff', '$dark-theme-color': '#32394D', } }, { name: 'green', showName: '孔雀绿', fileName: 'green', colors: { '$primary-color': '#2EC2AB', '$primary-color-hover': '#52cfb7', '$light-theme-color': '#46606f', '$dark-theme-color': '#07241E;', } }, { name: 'red', showName: '玳瑁红', fileName: 'red', colors: { '$primary-color': '#F15548', '$primary-color-hover': '#fe7a74', '$light-theme-color': '#2c343f', '$dark-theme-color': '#2C343F', } }, { name: 'purple', showName: '淡白紫', fileName: 'purple', colors: { '$primary-color': '#7A7DE5', '$primary-color-hover': '#a7acf2', '$light-theme-color': '#383a69', '$dark-theme-color': '#7A7DE5', } } ];
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。