# 更換主題
本項目基于 element-ui 默認視覺風格搭建了。如果對視覺風格有額外的要求可以按照[官方自定義主題指導](http://element-cn.eleme.io/#/zh-CN/component/custom-theme)。該方案是通過樣式變量覆蓋的方式。
## [#](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#%E6%A0%B7%E5%BC%8F%E8%A6%86%E7%9B%96)樣式覆蓋
element-ui 的通用樣式變量可能無法滿足所有定制需求,你可以通過覆蓋默認的組件樣式的方式實現。 由于 element-ui 的樣式我們是在全局引入的,所以你想在某個`view`里面覆蓋它的樣式就不能加 scoped,但你又想只覆蓋這個頁面的 element 樣式,你就可在它的父級加一個 class,以用命名空間來解決問題。或者使用[深度作用選擇器](https://vue-loader.vuejs.org/zh/guide/scoped-css.html#%E6%B7%B1%E5%BA%A6%E4%BD%9C%E7%94%A8%E9%80%89%E6%8B%A9%E5%99%A8)。
~~~
/* 你的命名空間 */
.article-page {
/* element-ui 元素 */
.el-tag {
margin-right: 0px;
}
}
~~~
一些全局的 element-ui 樣式修改可以在[@/src/styles/element-ui.scss](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/styles/element-ui.scss)中進行設置。
## [#](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#%E5%8A%A8%E6%80%81%E6%8D%A2%E8%82%A4)動態換膚
本項目提供了兩種動態換膚的功能,各有利弊,請結合個人需求自行選擇。
### [#](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#element-ui-%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E9%A1%B5%E9%9D%A2-%E6%8D%A2%E8%82%A4%E6%96%B9%E5%BC%8F)element-ui 官方文檔頁面 換膚方式
element-ui 升級為 2.0 之后官方文檔的右上角提供了動態換膚的功能,本項目也提供了改功能。 代碼地址:[@/src/components/ThemePicker](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/ThemePicker/index.vue)。
**簡單說明一下它的原理:**element-ui 2.0 版本之后所有的樣式都是基于 SCSS 編寫的,所有的顏色都是基于幾個基礎顏色[變量](https://github.com/PanJiaChen/custom-element-theme/blob/master/element-variables.scss)來設置的,所以就不難實現動態換膚了,只要找到那幾個顏色變量修改它就可以了。 首先我們需要拿到通過`package.json`拿到 element-ui 的版本號,根據該版本號去請求相應的樣式。拿到樣式之后將樣色,通過正則匹配和替換,將顏色變量替換成你需要的,之后動態添加`style`標簽來覆蓋原有的 css 樣式。
> ## TIP
>
> 這里需要獲取 element-ui 的版本號,從而鎖定版本,以免將來 Element 升級時受到非兼容性更新的影響。
~~~
const version = require('element-ui/package.json').version
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
this.getCSSString(url, chalkHandler, 'chalk')
getCSSString(url, callback, variable) {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
callback()
}
}
xhr.open('GET', url)
xhr.send()
}
~~~
**使用方式**
在項目中引入 ThemePicker 組件即可
~~~
import ThemePicker from '@/components/ThemePicker'
~~~
* 優點
* 無需準備多套主題,可以自由動態換膚
* 缺點
* 自定義不夠,只支持基礎顏色的切換
### [#](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#%E5%A4%9A%E5%A5%97%E4%B8%BB%E9%A2%98%E6%8D%A2%E8%82%A4)多套主題換膚
本方法就是最常見的換膚方式,本地存放多套主題,兩者有不同的命名空間,如寫兩套主題,一套叫`day-theme`,一套叫`night-theme`,`night-theme`主題都在一個`.night-theme`的命名空間下,我們動態的在 body 上 add`.night-theme`; remove`.night-theme`。
#### [#](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/theme.html#%E4%BD%BF%E7%94%A8)使用
> 我們這里基于官方的主題生成庫[element-theme](https://github.com/ElementUI/element-theme)進行了相應的改造。
首先我們下載[custom-element-theme](https://github.com/PanJiaChen/custom-element-theme)項目
~~~
git@github.com:PanJiaChen/custom-element-theme.git
~~~
之后全局安裝主題生成工具
~~~
npm i element-theme -g
~~~
進入項目目錄 安裝相關依賴
~~~
npm install
~~~
首先執行`et -i`生成`element-variables.scss`存放樣式變量的文件,然后進入`element-variables.scss`文件 修改你自己需要的變量,修改完成之后執行`et`, 編譯主題,最后執行`gulp`生成命名空間。所有生成文件在`dist`目錄下,你只需復制文件下所有內容到`vue-element-admin`項目中`src/assets/custom-theme`進行覆蓋替換就行
> ## TIP
>
> 如果需要修改打包生成樣式命名空間的名字 只要修改該[變量](https://github.com/PanJiaChen/custom-element-theme/blob/master/gulpfile.js#L6)即可

[更多動態換膚文章](https://segmentfault.com/a/1190000009762198#articleHeader2)