Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ionic 2 多主题、多租户构建方案探索 #4

Open
semlinker opened this issue Mar 3, 2017 · 0 comments
Open

Ionic 2 多主题、多租户构建方案探索 #4

semlinker opened this issue Mar 3, 2017 · 0 comments

Comments

@semlinker
Copy link
Owner

项目背景

公司的产品是一款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'
  ]
}

总结

目前的主题方案,还比较初级,后续还有很多地方需要优化和升级,我们会持续更新相关的内容,有兴趣的小伙伴可以一起探讨哈。

@semlinker semlinker changed the title 基于 Ionic 2 多主题、多租户构建方案探索 Ionic 2 多主题、多租户构建方案探索 Mar 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant