使用主题
部件的主题 key
Dojo 的主题框架使用“部件主题 key” 概念将重写的样式与对应部件的相关样式关联。覆盖的样式通常在主题中指定;但如果需要,也可以直接传给 theme
中间件的 classes
属性。
一个部件的主题 key 的确切格式为:
{package-name}/{widget-css-module-name}
其中 package-name
是项目 package.json
中 name
属性的值,widget-css-module-name
是部件使用的主 CSS 模块的文件名(不包括 .m.css
扩展名)。
主题 key 示例
给定如下项目:
package.json
{
"name": "my-app"
}
遵循部件的 CSS 模块命名规范时,一个 src/widgets/MyWidget.ts
使用的 CSS 模块名类似于 src/styles/MyWidget.m.css
。因此 MyWidget
的主题 key 为:
my-app/MyWidget
此处,部件的名称与其 CSS 模块文件的名称相同,但是开发人员要注意,不要将部件的主题 key 误认为就是部件的 TypeScript 类名。
再看第二个部件,没有遵循 CSS 模块的命名规范,如 src/widgets/BespokeWidget.ts
使用的 CSS 模块为 src/styles/BespokeStyleSheet.m.css
,则部件的主题 key 应改为:
my-app/BespokeStyleSheet
编写主题
主题就是一个 TypeScript 模块,会导出一个默认对象,其中将部件主题 key 映射到导入的类型化的 CSS 模块上。主题中的 CSS 模块与部件直接使用的常规模块相同。一旦应用程序应用了主题,则主题定义对象中的主题 key 标识的每一个部件的样式,都会被主题 key 对应的 CSS 模块中的样式覆盖。
以下是 MyWidget
部件完整主题中的一个简单示例(使用默认的 CSS 模块 MyWidget.m.css
),位于 my-app
项目中:
src/themes/myTheme/styles/MyWidget.m.css
.root {
color: blue;
}
src/themes/myTheme/theme.ts
import * as myThemedWidgetCss from './styles/MyWidget.m.css';
export default {
'my-app/MyWidget': myThemedWidgetCss
};
此处,MyWidget
遵循命名规范,将主样式类命名为 root
,这样 myTheme
就可以被 src/themes/myTheme/styles/MyWidget.m.css
CSS 模块中的 root
类覆盖掉。
通过主题 key my-app/MyWidget
,主题将新的 root
样式类关联到 MyWidget
上。当应用 myTheme
主题后,MyWidget
会将其颜色设置为蓝色,且不会再接收其初始 CSS 模块的 root
类中定义的其他样式。
为第三方部件搭建主题
应用程序的主题可能需要包含第三方部件使用的样式,比如Dojo 自带部件库中提供的样式。
@dojo/cli-create-theme
中提供了一些工具,使用 dojo create theme
CLI 命令,能为第三方部件快速生成主题脚手架。可通过以下方式在应用程序中安装:
npm install --save-dev @dojo/cli-create-theme
然后在项目根目录下按如下方式使用:
dojo create theme -n {myThemeName}
运行此命令,会在询问两个问题后开始创建 myThemeName
主题:
- What Package to do you want to theme?
- 答案应该是包含第三方部件的所有包,如
@dojo/widgets
。本命令会继续询问更多的包,直到用户结束此操作。
- 答案应该是包含第三方部件的所有包,如
- Which of the {third-party-package} theme files would you like to scaffold?
- 在回答第一个问题时,会显示第三方包中所有可主题化的部件。然后用户在其中选择一部分兼容的部件包含到输出的主题中,通常只选择在当前应用程序中实际用到的部件,确保主题足够小。
命令成功执行后,会在当前项目中创建几个文件:
src/themes/{myThemeName}/theme.ts
src/themes/{myThemeName}/{third-party-package}/path/to/{selectedWidget}.m.css
为所有 {selectedWidget}
创建的主题 CSS 模块都提供了可主题化的 CSS 选择器,然后就可以为 {myThemeName}
填充合适的样式规则。
兼容的包
任何包含 theme
目录的第三方包都是兼容的,其中既包含部件的 CSS 模块文件(*.m.css
),也包含对应的编译后的定义文件(*.m.css.js
- 详情参见分发主题)。
例如:
node_modules
└── {third-party-package}
└── theme
│ {widget}.m.css
│ {widget}.m.css.js
分发主题
Dojo 的 cli-build-theme
提供了一个 CLI 命令,构建的主题可分发给多个应用程序使用。它会创建出以各种不同方式使用主题所需的所有文件。
注意,当使用 dojo create theme
搭建新的主题时,并不需要使用 dojo build theme
,因为所有相关文件都已就位。这主要用于使用 @dojo/cli-build-app
或 @dojo/cli-build-widget
构建项目时来构建主题。
要使用此工具,在需要主题化的项目下安装 @dojo/cli-build-theme
:
npm install --save-dev @dojo/cli-build-theme
然后构建主题,请运行命令,并指定一个主题名以及一个可选的发布版本号:
dojo build theme --name={myThemeName} --release={releaseVersion}
如果没有指定 release
,则会使用 package.json
中的当前版本号。
运行该命令后,会在项目中创建一个 dist/src/{myThemeName}
文件夹,其中包含:
- 一个主题的
index.js
文件,会被导入并用于主题化应用程序或兼容的部件 - 主题中所有部件的 CSS 模块文件(
.m.css
)。这些文件可以通过主题组合功能直接引用,可用于基于新构建的主题来创建出自己主题的所有应用程序。 - 一个
assets
文件夹,包含主题文件夹中的所有字体和图片。 - 一个
index.css
文件,如果要使用整个主题,则需要将其导入到应用程序的main.css
中。 - 支持在自定义元素(custom elements)上使用主题的其他文件:
- 一个
{name}-{release}.js
文件,会使用全局的注册器注册主题(使用<script>
标签添加)。 - 一个
{name}-{release}.css
文件,使用<link rel="stylesheet">
标签添加。
- 一个
使用 Dojo 提供的主题
@dojo/themes
包提供了一组立即可用的主题,涵盖了 Dojo 自带部件库的所有部件。可以按原样使用主题库,或者作为基础组合出完整的应用程序主题。
-
要使用主题,在项目中安装
@dojo/themes
,比如使用npm i @dojo/themes
命令。然后,对于常规的 Dojo 应用程序: -
在项目的
main.css
文件中导入主题的 CSS 文件:@import '~@dojo/themes/dojo/index.css';
-
导入主题的 TypeScript 模块,然后使用:
import theme from '@dojo/themes/dojo'; render() { return w(Button, { theme }, [ 'Hello World' ]); }
如果尝试在 Custom elements 中使用它,则安装完 @dojo/themes
之后:
-
在
index.html
中添加 Custom elements 专用的主题 CSS 文件:<link rel="stylesheet" href="node_modules/@dojo/themes/dojo/dojo-{version}.css" />
-
在
index.html
中添加 Custom elements 专用的主题 JS 文件:<script src="node_modules/@dojo/themes/dojo/dojo-{version}.js"></script>