Vue项目动态主题切换

通常情况下,很多后台管理界面需要有好几套颜色的主题,我们的Vue项目已经集成了ElementUI,本来也支持主题定制,ElementUI使用了Sass开发样式,因此自定义样式也是很方便的。

自定义样式

参考:https://element.eleme.cn/#/zh-CN/component/custom-theme

主要就是修改ElementUI提供的变量,先根据实际情况修改变量值,然后引入ElementUI提供的scss:

目前我们把通用样式写到common.scss中,然后在index.scss中引入:

// 参考:https://element.eleme.cn/#/zh-CN/component/custom-theme
/* 改变主题色变量 */
$--color-primary: #545C64;
$--color-success: #27B6AF;
$--menu-background-color: #1D212A;
$--menu-item-font-color: #B3B8C3;
$--menu-item-hover-fill: #1F2D3D;
$--main-padding: 15px;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
// 通用的布局等样式
@import "../common";

common.scss片段:

// 自定义变量
$---menu--inline-background-color: #13161C !default;
$---index-header-height: 50px !default;
$---padding-common: 15px !default;
$---margin-common: 15px !default;
$---border-line-color: #E6E6E6 !default;
@import "~element-ui/packages/theme-chalk/src/index";
.el-menu-item.is-active {
  color: $--color-white;
  background-color: $--menu-item-hover-fill;
  font-weight: $--font-weight-primary;
}
// .............更多见GitHub源文件

然后在main.js中引入就可以了。

// 样式配置
import './assets/css/main.scss'

这样完成了主题的定制了,不过要实现多套主题切换的话,还有些需要处理

动态切换样式

动态主题切换一般有好几种方式:

  1. 切换主题的时候引入不同的css文件
    1. 需要的时候单独发起请求,按需加载css文件
  2. 切换主题的时候改变主题样式名称
    1. 多套css样式已经在css文件中
    2. 加载数据量比较大

其实Vue对css动态切换主题支持并不是太好,通常的css被编译处理之后加入页面,因此动态引入不同的css文件比较难做到。

我们这里选择第2种方式。

目录结构如下,图上是两个主题,defaultsimple

Vue项目动态主题切换

common.scss——引入ElementUI样式,并自定义一些变量和样式

themes/{themeName}/index.scss——定制变量

css/main.scss——样式入口

main.scss主要内容:

// 实际样式引入
.theme-simple {
  @import "src/assets/themes/simple/index";
}
.theme-default {
  @import "src/assets/themes/default/index";
}

sass样式这样引入之后所有样式定义自动在主题样式之下

切换主题

因为样式已经引入,只需要改变body的样式名称即可,调用$changeTheme(theme)

const $themeList = [
  {
    id: 'theme-default',
    name: '默认主题'
  }, {
    id: 'theme-simple',
    name: '简单主题'
  }
]    
Vue.prototype.$changeTheme = function (theme = $themeList[0]) {
    const body = document.querySelector('body')
    $themeList.forEach(t => {
        body.classList.remove(t.id)
    })
    body.classList.add(theme.id)
    store.dispatch('Theme/changeTheme', theme) // 暂时保存到store里面
}

实际效果参考下面的截图,更多样式可以在主题文件中再做定制。

默认主题:

Vue项目动态主题切换

紫色主题:

Vue项目动态主题切换

问题记录

目前遇到一个比较奇怪的问题,按照上面的方法做了之后,其他都显示正常,就是图标显示有问题,直接引入主题文件就是好的,放到主题样式之下就有问题。

// 这种写法图标正常显示
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "src/assets/themes/simple/index"
// 这种写法图标不显示,因此只能font-face做了特殊处理,暂不知道有没有更好的方法
$--font-path: '~element-ui/lib/theme-chalk/fonts';
.theme-default {
  @import "src/assets/themes/default/index";
}

针对font-face做了特殊处理就可以正常了:

main.scss中添加:

//***********这块font定义是为了修复问题********************
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@font-face {
  font-family: 'element-icons';
  src: url('#{$--font-path}/element-icons.woff') format('woff'), url('#{$--font-path}/element-icons.ttf') format('truetype'); 
  font-weight: normal;
  font-display: auto;
  font-style: normal;
}

GitHub地址:https://github.com/fugary/simple-element-ui-template

给TA打赏
共{{data.count}}人
人已打赏
运维

Vue项目ElementUI集成

2024-11-19 10:36:14

运维

Vue项目集成vuex-persistedstate

2024-11-19 10:36:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索