Angular8 主题色切换(封装成Directive)

27 篇文章 0 订阅
5 篇文章 0 订阅

一、概述

切换主题色思路:通过点击或者切换选择一种已经定义好的主题色,将当前主题色保存在缓存中,通过修改全局的setProperty属性,改变背景色,字体色的变量值。

二、前景知识

2.1、SCSS使用(var --)

2.2、设置css属性dom.setProperty(‘background-color’:‘yellow’)

2.3、Angular8 Directive使用

2.4、subScription,ElementRef,localStroage

三、文件目录

在这里插入图片描述

四、实例展示

3.1、app.component

<app-nav appTheme></app-nav>
.app-wrap {
    color: var(--textColor);
    background-color:var(--backgroundColor);
}
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss', './app.component.css']
})
export class AppComponent {
  title = 'demos-theme';
}

3.2、nav.component

<div class="nav-wrap">
    <div class="nav-wrap-header-left">
        路由
    </div>
    <div class="nav-wrap-header-right">
        <button class="btn-default" (click)="changeTheme()">切换主题--{{themName}}</button>
    </div>
<div>
import { Component, OnInit } from '@angular/core';
import { ThemeService } from 'src/app/core/modules/themes/theme.service';

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.scss', './nav.component.css']
})
export class NavComponent implements OnInit {
  public themName: string;

  constructor(private themeService: ThemeService) { }

  ngOnInit() {
    this.themeService.getActiveTheme().subscribe(themName => {
      this.themName = themName;
    });
  }
  // 点击切换主题色
  changeTheme() {
    console.log(this.themName);
    if (this.themName === 'LIGHT_THEME') {
      this.themName = 'BLACK_THEME';
      this.themeService.setActiveTheme(this.themName);
    } else {
      this.themName = 'LIGHT_THEME';
      this.themeService.setActiveTheme(this.themName);
    }
  }

}

.nav-wrap {
    background-color:var(--backgroundColor);
    font-size: 16px;
    color: var(--textColor);
    height: 48px;
    line-height: 48px;
    .nav-wrap-header-left {
        float: left;
    }
    .nav-wrap-header-right {
        float: right;
        .btn-default {
            height: 32px;
            background-color:var(--textColor);
            color: var(--backgroundColor);
            outline: none;
            border:0px;
            border-radius: 5px;
        }
    }
    
}

3.3、core/themes/

import { Directive, OnDestroy, OnInit, ElementRef, Inject } from '@angular/core';
import { Subscription, UnsubscriptionError } from 'rxjs';
import { DOCUMENT } from '@angular/common';
import { ThemeService } from './theme.service';
import { THEMES } from './themes.constants';

@Directive({
  selector: '[appTheme]'
})
export class ThemeDirective implements OnInit, OnDestroy {
  private themeName = 'LIGHI_THEME';
  private themeServiceSubscription: Subscription;
  constructor(
    private elementRef: ElementRef,
    @Inject(DOCUMENT) private document: any,
    private themeService: ThemeService
  ) { }
  ngOnInit() {
    this.updateTheme(this.themeName);
    this.themeService.getActiveTheme().subscribe(themeName => {
      this.themeName = themeName;
      this.updateTheme(this.themeName);
    });
  }
  updateTheme(themeName) {
    const element = this.elementRef.nativeElement;
    console.log(element);
    const theme = THEMES[themeName];
    // tslint:disable-next-line:forin
    for (const key in theme) {
      element.style.setProperty(key, theme[key]);
      this.document.body.style.setProperty(key, theme[key]);
    }
  }
  ngOnDestroy() {
    if (this.themeServiceSubscription) { this.themeServiceSubscription.unsubscribe(); }
   }
}

export const THEMES = {
    LIGHT_THEME: {
        '--backgroundColor': '#008afe',
        '--textColor': '#fff',
        '--fontSize': '14px'
    },
    BLACK_THEME: {
        '--backgroundColor': '#f2f2f2',
        '--textColor': '#000',
        '--fontSize': '16px'
    },
    DARK_THEME: {
        '--backgroundColor': '#aaaaaa',
        '--textColor': '#fff',
        '--fontSize': '18px'
    }
};
export const LIGHT_THEME = 'LIGHT_THEME';
export const BLACK_THEME = 'BLACK_THEME';
export const DARK_THEME = 'DARK_THEME';
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { LIGHT_THEME } from './themes.constants';

@Injectable({
  providedIn: 'root'
})
export class ThemeService {
  private activeTheme = new BehaviorSubject(localStorage.getItem('activeTheme') || LIGHT_THEME);
  constructor() { }
  public getActiveTheme() {
    return this.activeTheme.asObservable();
  }
  public setActiveTheme(name) {
    localStorage.setItem('activeTheme', name);
    this.activeTheme.next(name);
  }
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ThemeDirective } from './theme.directive';


@NgModule({
  declarations: [ThemeDirective],
  imports: [
    CommonModule,
    FormsModule
  ],
  exports: [ThemeDirective]
})
export class ThemeModule { }

3.4、切换主题效果图

在这里插入图片描述

五、项目地址

gitHub项目地址
git clone

六、学习地址

scss基础知识
主题色切换
CSSStyleDeclaration setProperty() 方法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值