專案背景
公司的產品是一款2B的線上教育產品,已有的客戶大多數都有定製化的需求,主要包括UI主題和二次開發的功能。本文圍繞的主要內容是如何基於 Ionic 2 平臺提供的工具,實現靈活的多主題方案。
Ionic 2 提供的主題方案
Ionic 2 使用 $color map 的 key 作為元件的輸入屬性,用於設定元件的樣式。$colors map 中的內容如下:
// variables.scss 檔案(路徑: src/theme/variables.scss )
$colors: {
primary: #387ef5,
secondary: #32db64,
danger: #f53d3d,
light: #f4f4f4,
dark: #222,
favorite: #69BB7B
};
使用示例:
<ion-item-options side="right">
<button ion-button color="primary" (click)="buttonOne(page.title)">
<ion-icon name="text"></ion-icon>
BUTTON 1
</button>
<button ion-button color="secondary" (click)="buttonTwo(page.title)">
<ion-icon name="call"></ion-icon>
BUTTON 2
</button>
</ion-item-options>
此外 $colors map 還支援字面量形式,物件內部有 base 和 contrast 屬性
-
base: 用於標識元件的背景顏色
-
contract: 用於標識元件的文字顏色
備註:Ionic 框架內部使用 node_modules/ionic-angular/themes/ionic.functions.scss 中的顏色處理函式,解析 map中設定的 base 和 contrast 值。
使用示例:
$colors: (
twitter: {
base: #55acee,
contrast: #ffffff
},
facebook: {
base: #38669f;
contrast: #ffffff
}
);
切換 Ionic 的主題:
在 src/theme/variables.scss 檔案中匯入 Ionic 預置的黑色主題
@import "ionic.build.dark";
自定義主題
-
修改Variables檔案中,$colors map 定義的屬性值
-
覆寫已有的變數值
-
自定義 Sass 變數
-
自定義元件樣式
-
配置元件的mode(模式)
1.修改Variables檔案中,$colors map 定義的屬性值
// variables.scss 檔案(路徑: src/theme/variables.scss )
$colors: (
primary: #387ef5,
secondary: #32db64,
danger: #f53d3d,
light: #f4f4f4,
dark: #222,
favorite: #69BB7B,
twitter:(
base: #55acee,
contrast: #ffffff
),
facebook:(
base: #38669f,
contrast: #ffffff
)
);
<button ion-button color="facebook" (click)="buttonOne(page.title)">
<ion-icon name="text"></ion-icon>
BUTTON 1
</button>
<button ion-button color="twitter" (click)="buttonTwo(page.title)">
<ion-icon name="call"></ion-icon>
BUTTON 2
</button>
在任意自定義元件中,可以使用 color 函式獲取相應的顏色值:
my-component {
background: color($colors, twitter, base);
}
2.覆寫已有的變數值
$text-color: #686868;
$font-size-base: 1.6rem;
$list-ios-background-color: #ffffff;
$list-md-background-color: #ffffff;
$list-wp-background-color: #ffffff;
Ionic 中可以覆寫的 Sass 變數列表:overriding-ionic-variables
3.自定義 Sass 變數
// variables.scss 檔案(路徑: src/theme/variables.scss )
$colors: (
...
);
$my-padding: 20px; // Custom Sass variables
4.自定義元件樣式
// about.scss 檔案 (路徑: myApp/src/pages/about/about.scss)
page-about {
.isSuccess {
color: #1E88E5 !important;
}
.isError {
color: #D43669 !important;
}
}
about.scss 檔案中的內容將會被編譯到 main.css檔案中
page-home .isSuccess {
color: #1E88E5 !important;
}
page-home .isError {
color: #D43669 !important;
}
5.配置元件的mode(模式)
每個平臺都有對應的模式:
-
md (Android)
-
ios (iOS)
-
wp (Windows Phone)
-
md (Core – used for any platform other than the above)
我們也可以通過 Ionic 的 Config API 方便地配置 mode 下可配置欄位的值,具體如下:
imports: [
IonicModule.forRoot(MyApp, {
backButtonText: "",
backButtonIcon: "md-arrow-back",
iconMode: "md",
modalEnter: "modal-md-slide-in",
modalLeave: "modal-md-slide-out",
pageTransition: "md"
});
]
以上的配置資訊,用於設定在 iOS 平臺下,App 的風格採用 Android material 設計。
我們也可以單獨針對特定的平臺,進行配置:
imports: [
IonicModule.forRoot(MyApp, {
platforms: {
android: {
backButtonText: "",
backButtonIcon: "md-arrow-back",
iconMode: "md",
modalEnter: "modal-md-slide-in",
modalLeave: "modal-md-slide-out",
pageTransition: "md",
},
ios : {
backButtonText: "Previous",
backButtonIcon: "ios-arrow-back",
iconMode: "ios",
modalEnter: "modal-ios-slide-in",
modalLeave: "modal-ios-slide-out",
pageTransition: "ios",
}
}];
此外,通過 Config API 提供的方法,我們可以在 TypeScript classes 中,方便的設定特定平臺下的配置資訊,具體如下:
config.set(`ios`, `textColor`, `#AE1245`);
該方法接受三個引數:
-
platform (optional – `ios` or `android`, if omitted this will apply to all platforms)
-
key (optional – The name of the key used to store our value I.e. `textColor`)
-
value (optional – The value for the key I.e. `#AE1245`)
通過 Config API 提供的 get 方法獲取配置的值:
config.get(`textColor`);
我們也能夠在元件層級,方便地配置元件,如通過 ion-tabs 的輸入屬性 tbasPlacement 設定 ion-tabs 元件的顯示位置:
<ion-tabs tabsPlacement="bottom">
<ion-tab tabTitle="Dash" tabIcon="pulse" [root]="tabRoot"></ion-tab>
</ion-tabs>
配置指定平臺的樣式
Ionic 使用 mode 來定義元件的外觀。每個平臺都有預設的 mode , 任何 mode 下的樣式資訊,都能被我們覆寫。我們可以在 ion-app 中指定mode的值,具體如下:
<ion-app class="md">
覆寫 md 模式下的樣式
.md button {
text-transform: capitalize;
}
覆寫 md 下 Sass 變數的值
$button-md-border-radius: 8px;
// Ionic Sass
// ---------------------------------
@import "ionic";
動態的設定元件的屬性
<ion-list [attr.no-lines]="isMD ? `` : null"
EXE – 多主題、多租戶構建方案
Ionic 2 團隊基於 webpack 開發了專案的構建工具 – ionic-app-scripts
Ionic-app-scripts 的功能很強大,通過它我們可以非常靈活地控制專案構建的每個環節。比如,可以通過 command-line 指定某個環節使用的配置檔案:
npm run build --rollup ./config/rollup.config.js
此外,也可以在 package.json 檔案中設定配置檔案的路徑和系統構建引數的值:
"config": {
"t": "sf", // 租戶的名稱
"l": "zh-cn", // 預設的語言包
"ionic_sass": "./config/sass.config.js", // 自定義Sass構建環節的配置檔案
"ionic_copy": "./config/copy.config.js" // 自定義Copy構建環節的配置檔案
}
copy.config.js 檔案 – 用於配置專案構建過程中檔案拷貝的環節:
// copy.config.js 程式碼片段
module.exports = {
copyResources: {
src: [`{{ROOT}}/materials/` + process.env.npm_package_config_t + `/resources/**/*`],
dest: `{{ROOT}}/resources`
}
}
備註:根目錄下的 `{{ROOT}}/materials/` 目錄下,用於存放不同租戶自定義的資源,如 icon.png 和 splash.png 等圖片資原始檔。
sass.config.js 檔案 – 用於配置專案構建過程中 Sass 編譯的環節:
// sass.config.js 程式碼片段
module.exports = {
variableSassFiles: [
`{{SRC}}/theme/variables.scss`,
`{{SRC}}/theme/${process.env.npm_package_config_t}.theme.scss`
]
}
備註:不同租戶的主題的命名規則:租戶名 + .theme.scss 。專案構建時通過動態設定 process.env.npm_package_config_t 的值,來實現動態構建。
我有話說
1.為什麼在 variables.scss 檔案中 @import “ionic.globals” 、@import “ionic.ionicons” 能正常匯入對應的檔案:
在 Scss 檔案中匯入其他依賴的 *.scss 檔案,我們一般使用相對路徑的方式。但 variables.scss 匯入 ionic.globals 或 ionic.ionicons 檔案卻不是使用相對路徑的方式,此外在我們專案的 src 目錄下也沒有對應的檔案。怎麼會那麼神奇,剛開始接觸的時候,我也一臉懵逼。後面通過深入發掘,終於解開了疑惑。
看完下面的程式碼,你應該也猜到了答案:
// sass.config.js 程式碼片段
{
...,
includePaths: [
`node_modules/ionic-angular/themes`,
`node_modules/ionicons/dist/scss`,
`node_modules/ionic-angular/fonts`
]
}
總結
目前的主題方案,還比較初級,後續還有很多地方需要優化和升級,我們會持續更新相關的內容,有興趣的小夥伴可以一起探討哈。