Angular换肤方案一主题切换

25次阅读

共计 1821 个字符,预计需要花费 5 分钟才能阅读完成。

效果图:
框架版本:
第一种方案:使用 scss 预处理器。思路是通过点击事件,控制 body 上自定义属性的值,利用 scss @mixin 指令实现切换 CSS 样式。具体代码实现如下

  1. 在 assests 文件夹下新建 base.scss(主题参数变量)和 mixin.scss 两个样式文件
    base.scss:

    $background-color-blue: #1dd3f3;
    $background-color-black: #0c0b0b;

    mixin.scss:

    @import './base.scss';
    @mixin bg_color() {:host-context([data-theme='blue']) & {background-color: $background-color-blue;}
      :host-context([data-theme='black']) & {background-color: $background-color-black;}
    }
  2. 全局 styles.scss 样式文件引入 mixin.scss 文件

    @import './assets/scss/mixin.scss';
  3. 在 app.component.scss 中应用定义在 mixin.scss 文件中的样式

    @import '../styles.scss';
    .toolbar_scss{@include bg_color}
  4. 修改 app.component.html 文件(使用 mat-menu 标签需要安装 material 组件库,执行 ng add @angular/material 命令后,在 app.module.ts 中引入 MatIconModule, MatMenuModule 即可)

    <div class="spacer">
      <button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Example icon-button with a menu">
        <mat-icon>more_vert</mat-icon>
      </button>
      <mat-menu #menu="matMenu" style="margin-top: 68px">
        <button mat-menu-item (click)="changeTheme('blue')">
          <mat-icon>dialpad</mat-icon>
          <span> 蓝色 </span>
        </button>
        <button mat-menu-item (click)="changeTheme('black')">
          <mat-icon>voicemail</mat-icon>
          <span> 黑色 </span>
        </button>
      </mat-menu>
    </div>
  5. app.component.ts 文件通过点击事件控制 body 上自定义属性的值,并存入 localStorage 中

      export class AppComponent {
        title = 'angular-ui';
        themeUI: string;
      
        ngOnInit() {this.setTheme();
        }
      
        changeTheme(theme: string) {const body = document.getElementsByTagName('body')[0];
          const currentTheme = body.getAttribute(`data-theme`);
          if (currentTheme !== theme) {body.setAttribute('data-theme', theme);
            this.saveTheme(theme)
          }
        }
      
        saveTheme(theme: string) {localStorage.setItem(`theme`, theme);
        }
      
        setTheme() {this.themeUI = localStorage.getItem('theme') || 'blue'
          const body = document.getElementsByTagName('body')[0];
          body.setAttribute('data-theme', this.themeUI);
        }
      }

    总结:@mixin bg_color() 生效原理利用了:host-context() 伪类选择器。它类似 :host() 形式使用。它在当前组件宿主元素的祖先节点中查找 CSS 类,直到文档的根节点为止。
    参考:https://segmentfault.com/a/11…

正文完
 0