dojo dragon main logo

介绍

作为一项基于 HTML 的技术,Dojo 利用 CSS 对框架中的元素以及使用它开发的应用程序进行样式化。

Dojo 提倡对单个小部件进行封装的结构化样式化,以实现最大程度的重用,以及简化应用程序中所有小部件的演示性主题化。这种模式为用户提供了一种可预测的方式来设置应用程序的样式和主题,即使使用来自 Dojo 的 @dojo/widgets、第三方提供商或任何可能为特定应用程序在内部开发的小部件的混合。

功能 描述
每个小部件的样式表 CSS 模块 可用于定义作用域限定于单个小部件的样式表,避免潜在的交叉污染和样式名称冲突。小部件可以通过类型化的 CSS 模块导入和 IDE 自动完成功能来引用其确切的 CSS 类名。
强大的主题支持 可主题化的小部件可以轻松开发,允许简化和集中化的整个应用程序主题化,以及在需要时进行单个实例、目标样式调整和覆盖。 CLI 工具可用 来支持分发自定义主题。
响应式主题更改响应 与 Dojo 应用程序中的其他响应式状态更改类似,当在小部件级别或整个应用程序中进行主题更改时,只有受影响的小部件将重新渲染。
CSS 属性 CSS 模块可以使用 CSS 自定义属性和 var() 来利用主题变体属性和颜色。
简化的第三方小部件主题化 应用程序可以轻松地扩展其主题以涵盖第三方小部件,例如来自 Dojo 的原生 小部件库 的小部件,Dojo 还提供 开箱即用的主题,应用程序可以以此为基础构建自己的主题。 CLI 工具可用 来简化主题创建和组合。

基本用法

注意:以下示例按线性顺序相互构建。单个示例保持简短,仅突出显示与任何先前示例相关的更改。

这些示例假设一个具有以下名称的应用程序

package.json

{
	"name": "my-app"
}

当指定 小部件主题键 时,应用程序名称变得相关。

设置小部件的样式

  • 为小部件定义一个 CSS 模块
  • 在小部件的 TypeScript 代码中使用相应的类型化样式类

src/styles/MyWidget.m.css

.root {
	font-family: sans-serif;
}

src/widgets/MyWidget.tsx

import { create, tsx } from '@dojo/framework/core/vdom';

import * as css from '../styles/MyWidget.m.css';

const factory = create();

export default factory(function MyWidget() {
	return <div classes={[css.root]}>My Widget</div>;
});

使小部件可主题化

src/widgets/MyWidget.tsx

import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import * as css from '../styles/MyWidget.m.css';

const factory = create({ theme });

export default factory(function MyWidget({ middleware: { theme } }) {
	const { root } = theme.classes(css);
	return <div classes={[root]}>My Widget</div>;
});

在小部件中使用主题变体

  • 在小部件的 root 上设置 theme.variant 类。
  • css 属性在正确的 DOM 级别应用,不会泄漏到小部件的 DOM 之外。

src/widgets/MyWidget.tsx

import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import * as css from '../styles/MyWidget.m.css';

const factory = create({ theme });

export default factory(function MyWidget({ middleware: { theme } }) {
	const { root } = theme.classes(css);
	const variantRoot = theme.variant();
	return <div classes={[root, variantRoot]}>My Widget</div>;
});

创建主题

  • 使用自定义主题样式属性覆盖小部件的默认 CSS 类
  • 通过适当的 小部件主题键 将一个或多个覆盖链接到 主题结构

src/themes/MyTheme/MyWidget.m.css

.root {
	color: hotpink;
	background-color: slategray;
}

src/themes/MyTheme/theme.ts

import * as myWidgetCss from './MyWidget.m.css';

export default {
	'my-app/MyWidget': myWidgetCss
};

创建主题变体

  • 将主题变量作为 CSS 自定义属性 放置到 variant 模块中
  • 通过 var() 引用自定义属性
  • 不依赖于局部变量或通用的 variables.css 文件。

src/themes/variants/default.m.css

/* single root class */
.root {
	--foreground: hotpink;
	--background: slategray;
}

src/themes/MyTheme/MyWidget.m.css

.root {
	color: var(--foreground);
	background-color: var(--background);
}

src/themes/MyTheme/index.tsx

import * as defaultVariant from './variants/default.m.css';
import * as myWidgetCss from './MyWidget.m.css';

export default {
	theme: {
		'my-app/MyWidget': myWidgetCss
	},
	variants: {
		default: defaultVariant
	}
};

指定默认应用程序主题

theme 中间件可用于设置应用程序主题。要设置“默认”或初始主题,可以使用 theme.set 函数,并使用 theme.get 函数来确定是否需要设置主题。设置默认主题应在应用程序的顶级小部件中完成。

src/App.tsx

import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import myTheme from '../themes/MyTheme/theme';

const factory = create({ theme });

export default factory(function App({ middleware: { theme }}) {
	// if the theme isn't set, set the default theme
	if (!theme.get()) {
		theme.set(myTheme);
	}
	return (
		// the application's widgets
	);
});

注意:当同时使用基于函数的小部件和基于类的小部件时,需要将主题注册到应用程序注册表中。当使用任何基于类的依赖项(例如 @dojo/widgets)时,这一点很重要。有关更多详细信息,请参阅 基于类的主题化部分

设置主题变体

如果使用具有 variants 的主题,则会自动选择 default 变体。使用 theme.set 函数来设置不同的变体 - 传递的变体名称必须是主题导出的 variants 的键。

import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import myTheme from '../themes/MyTheme/theme';

const factory = create({ theme });

export default factory(function App({ middleware: { theme }}) {
	// if the theme isn't set, set the default theme
	if (!theme.get()) {
		theme.set(myTheme, 'variant-name');
	}
	return (
		// the application's widgets
	);
});

在应用程序中更改主题

src/widgets/ThemeSwitcher.tsx

import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import myTheme from '../themes/MyTheme/theme';
import alternativeTheme from '../themes/MyAlternativeTheme/theme';

const factory = create({ theme });

export default factory(function ThemeSwitcher({ middleware: { theme } }) {
	return (
		<div>
			<button
				onclick={() => {
					theme.set(myTheme);
				}}
			>
				Use Default Theme
			</button>
			<button
				onclick={() => {
					theme.set(alternativeTheme);
				}}
			>
				Use Alternative Theme
			</button>
		</div>
	);
});