Angular 不依赖第三方库实现动态 Theme

天魂
Autor 天魂 一个死磕 Angular 的逼粉

Angular 不依赖第三方库实现动态 Theme

用户能够自己选择系统的外观一直以来都是很酷的功能,用户能实现完全的自定义,按自己的喜好设置不同的 theme。

在 Angular 构建的程序中也能很轻易实现。方法有很多种,比如利用Angular Material 组件库,里面内置了 theme 能用很少的代码实现动态 theme。

尽管利用组件库是一个不错的选择,但并非所有人都会使用 Material 样式。而且仅仅是为了实现动态 theme 就要引入一个组件库那就有点扯了,没人愿意这么做。

因此就有了用原生实现动态 theme 的骚操作 → 「Sass + CSS 自定义变量」

如果对 CSS 自定义属性很懵逼,点这里帮你解决疑惑。

单独用 Sass 变量也可以创建预设的 theme,但它无法用 JavaScript/TypeScript 控制,所以还得配合 CSS 自定义属性达到目的。

示例代码

骚操作

核心原理:结合 Scss map 和 CSS 自定义属性。

theme.scss

5-28行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// default colors
.theme-wrapper {
  --cardColor: #CCC;
  --cardBackground: #FFF;
  --buttonColor: #FFF;
  --buttonBackground: #FFF;
  --navColor: #FFF;
  --navBackground: #FFF;
  --footerColor: #FFF;
  --footerBackground: #FFF;
  --footerAlignment: left;
}

$variables: (
  --cardColor: var(--cardColor),
  --cardBackground: var(--cardBackground),
  --buttonColor: var(--buttonColor),
  --buttonBackground: var(--buttonBackground),
  --navColor: var(--navColor),
  --navBackground: var(--navBackground),
  --footerColor: var(--footerColor),
  --footerBackground: var(--footerBackground),
  --footerAlignment: var(--footerAlignment)
);

设置默认值并将其传入 sass map 中。

function.scss

2-4行

1
2
3
@function var($variable) {
    @return map-get($variables, $variable);
}

创建一个函数从全局 sass map 中返回 css 自定义属性

card.component.scss

1-6行

1
2
3
4
5
6
7
8
9
@import '../../theme';
@import '../../functions';

.card {
  background-color: var(--cardBackground);
  color: var(--cardColor);

  ...
}

card 组件中 import function.scsstheme.scss Sass 文件,用来使用已定义的变量,该变量的值在重新提交主题选择组件表单是会更改。

theme-picker.component.ts

12-25行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
onSubmit(form) {
    this.global(form.value);
}

global(stylesheet) {
    ...

    // Navigation Styles
    if (stylesheet.globalNavColor) {
        this.themeWrapper.style.setProperty('--navColor', stylesheet.globalNavColor);
    }
    if (stylesheet.globalNavBackground) {
        this.themeWrapper.style.setProperty('--navBackground', stylesheet.globalNavBackground);
    }

    ...
}

global 方法检查该特定变量是否存在值,然后将每个 CSS 自定义属性值替换为新输入的变量值。

💡 后期 Magic Skill 会添加切换 light/dark 模式 theme 的功能,具体技术细节会在「web 前端骚操作」知识星球中分享
评分:

🌀 Summary

# 扫码加入「web 前端骚操作」社群 #
🌈 社群介绍
comments powered by Disqus