A用戶:我喜歡亮色!B用戶:我喜歡暗色系!...在實際的開發場景中,主題需求通常都是必不可少的,那咱們如何簡單地實現咱們想要的效果呢!css
話很少說,咱們先看一下demo效果html
實現思路:在頁面的載體上自定義一個屬性標籤,用於記錄切換不一樣的主題,而後咱們的css文件會根據屬性標籤值的改變而加載不一樣樣式,來實現咱們切換主題的效果。乾巴巴的描述,理解起來有點晦澀難懂,這裏我以本身寫的demo爲例,和你們一塊兒交流探討。前端
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
</head>
<body customize-theme-style="dark">
<app-root></app-root>
>
</body>
</html>
複製代碼
目前不少單頁面應用都會有一個index.html載體文件,路由<app-root></app-root>
掛載在body
節點上,因此咱們的頁面組件都是掛載在body
上,那麼咱們在body
節點上定義一個customize-theme-style="dark"
屬性標籤用於記錄主題狀態的切換。接下來就是css會根據主題狀態的切換來改變主題樣式。 我這裏CSS 預處理語言用的是less(若是你用的是sass,或者是其餘的css預處理語言,思路都是相同的,語法上有些許不一樣而已),在資源文件夾裏建一個styles用於存放咱們的less樣式文件,demo的編譯環境是angular8.0,因此咱們要在angular.json腳手架文件聲明咱們新建的資源文件(這裏我就不詳細說明配置過程了,不一樣的前端框架,配置過程不一樣,但框架歷來不是技術實現的障礙,思路是同樣的), json
// 暗黑主題
[customize-theme-style='dark'] {
//背景
.alain-default {
background: @background-color;
}
//表格
.ant-table-thead>tr>th {
background-color: @table-head-color;
color: @font-color;
}
......
}
// 亮色主題
[customize-theme-style='light'] {
......
}
......
複製代碼
主題狀態的改變會加載不一樣的css樣式,接下來就是如何改變主題樣式狀態了sass
實現思路:咱們將用戶設置的主題狀態用localStorage
存儲在本地,若是用戶沒有設置,就加載默認主題。bash
//獲取用戶上次設置的主題
this.themeSkin = this.storageService.getStorageValue('customize-theme');
if (this.themeSkin) {
//設置主題
const body = document.getElementsByTagName('body')[0];
body.setAttribute('customize-theme-style', this.themeSkin);
}
//切換主題
changeSkin(skin) {
const body = document.getElementsByTagName('body')[0];
body.setAttribute('customize-theme-style', skin);
//存儲主題
this.storageService.setStorageValue('customize-theme', skin);
}
複製代碼
完成以上步驟就基本上實現了自定義主題的切換需求。前端框架
然而事情並無這麼簡單!!!app
如今的框架都是提倡頁面組件化,那麼咱們本身寫的組件怎麼適配主題呢? 所謂的適配也就是讓組件讀取當前載體文件body
節點(根節點)上的主題屬性值,這個也不難作到。 舉個栗子:框架
//自定義組件中的樣式
:host-context([customize-theme-style='dark']) h4 {
.mixin-font-color('dark');
}
:host-context([customize-theme-style='light']) h4 {
.mixin-font-color('light');
}
//index.less
.mixin-font-color(@a) when(@a='dark') {
color: #ffffff;
}
.mixin-font-color(@a) when(@a='light') {
color: #212121;
}
複製代碼
編譯後的css樣式: [customize-theme-style='dark'][_nghost-fkw-c5] h4[_ngcontent-fkw-c5], [customize-theme-style='dark'] [_nghost-fkw-c5] h4[_ngcontent-fkw-c5] { color: #ffffff; }less
:host-context()僞類選擇器能夠讀取最外層的掛載點上的屬性,經過這一特性就能實現組件主題化了 (API:angular.io/guide/compo…) 這裏就給咱們的組件中標題生成了一個惟一的樣式。 至此,咱們的主題需求問題就迎刃而解了。 若是有什麼疑問或者你有更好的解決方案,歡迎留言交流,謝謝~