日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

angular cli 切换 css_漫谈 Angular 定制主题的四种方式

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 angular cli 切换 css_漫谈 Angular 定制主题的四种方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

主題定制是提升用戶體驗最常見的一種,前端框架眾多,主題定制方式卻異曲同工,下面來介紹一下 Angular 中實現主題定制的四種方式。

1. webpack loader

React 版本的 Ant Design 使用 less-loader 加載 globalVars 與 modifyVars 變量,并通過 less 的 render 方法傳遞 callback 到 loader 來實現的項目的主題修改功能。

目前絕大部分的 angular 項目同樣使用 webpack 打包方案。顯然,相同的主題修改方案在 angular 中一樣適用。

webpack 打包 less

  • webpack 本身并不具備打包 less 文件的功能,最終實現該部分功能的是 less-loader,該加載器把 less 轉為 CSS,在 webpack 中每個文件或模塊都是有效的 JS 模塊,因此我們還需要 css-loader 將CSS樣式文件轉換為變成 JS 模塊。
  • 這時我們已經有了生成的 dist/style.js,在這個模塊中只是將樣式導出為字符串并存放于數組中,我們需要 style-loader 將該數組轉換成 style 標簽。
  • 最后我們還需要將 dist/style.js 自動導入 到 html 中,html-webpack-plugin 可以幫我們實現這部分功能。
  • 除了以上這些 loader,我們可能還需要 autoprefixer、cssnano 和 postcss-loader 等,有興趣的同學可以自行了解。

modifyVars

上面介紹的 less-loader 可以幫忙我們實現主體定制,通過一下這兩個配置,我們就可以把部分樣式抽出變量,通過不同的變量組合成不同的主題:

  • globalVars:相當于給每個 less 文件頂部增加一行 @VariableName: xx;
  • modifyVars:相當于給每個 less 文件底部增加一行變量 @variable:xx;
  • custom-webpack

    angular-cli 提供了 custom-webpack 的 builder,可以和 angular-cli 合并使用,通過 builder 重寫 webpack 中的 less-loader 的配置,然后利用 modifyVars 實現主題定制。

  • 安裝 npm i -D @angular-builders/custom-webpack
  • 在根目錄新建 webpack 配置文件 extra-webpack.config.js
  • module.exports = {module: {rules: [{test: /.css$/,use: ["style-loader","css-loader"]},{test: /.less$/,use : [{loader : "less-loader",options: {modifyVars: { // 修改主題變量"primary-color": "red"},javascriptEnabled: true}}]}]} }

    3.在 angular.json 中使用 @angular-builders/custom-webpack:browser

    "architect": {"build": {+ "builder": "@angular-builders/custom-webpack:browser",- "builder": "@angular-builders/build-angular:browser","options": {"customWebpackConfig": {"path": "./extra-webpack.config.js"},"outputPath": "dist/custom-webpack","index": "src/index.html","main": "src/main.ts","polyfills": "src/polyfills.ts","tsConfig": "tsconfig.app.json","assets": ["src/favicon.ico","src/assets"],"styles": ["src/styles.less"]}...} }

    這樣就可以實現 less 原理的主題定制了,當然 custom-webpack 不僅僅可以做到 less-loader 的重寫,它還可以利用 webpack 實現更多功能,具體研究我們在下一篇文章再來探討;

    如果你想進一步了解在 angular cli 中自定義 webpack 打包的方案,可以參考這篇文章

    筆者準備好了可以直接使用的源代碼,方便大家查看 點擊查看源碼

    純 webpack 打包

    如果開發者的項目未使用 Angular CLI,也可以通過同樣的方式實現自己的 webpack 打包器:

  • 在根目錄添加 webpack.config.js 文件。
  • 運行命令 webpack 或者 webpack-dev-serve,即可查看效果。
  • 筆者準備好了可以直接使用的源代碼,方便大家查看 點擊查看源碼

    可能很多開發者并不熟悉 less,開發過程中大多用純 CSS,純 CSS 能否實現主題定制了?答案是肯定的,下面我們來探討一下純 CSS 的主題定制。

    2. CSS Variable

    CSS3 提供了 Variable, 利用 angular Directive 指令,動態修改 CSS Variable,從而得到主題切換的效果。注意:CSS Variable 支持的瀏覽器可以在 這里 查看

    .element{--main-bg-color: brown;} // 聲明局部變量 .element{background-color: var(--main-bg-color);} // 使用局部變量 :root { --global-color: #666; --pane-padding: 5px 42px; } // 聲明全局變量 .demo{ color: var(--global-color); } // 使用全局變量

    有了以上的的基礎知識,我們很容易想到如何在 angular 中實現基于 css Variable 的主題切換功能,我們只需要一個 Directive 可以根據 @Input 輸入動態切換 style 即可。

    1.創建一個指令:ThemeDirective,用來給需要 CSS 變量的標簽添加樣式

    import { Directive, ElementRef, Input, OnChanges } from '@angular/core'; @Directive({selector: '[dtTheme]' }) export class ThemeDirective implements OnChanges {@Input('dtTheme') theme: {[prop: string]: string};constructor(private el: ElementRef<HTMLElement>) {}ngOnChanges() {Object.keys(this.theme).forEach(prop => {this.el.nativeElement.style.setProperty(`--${prop}`, this.theme[prop]);});} }

    2.創建一個組件:app.component.ts

    import { Component } from '@angular/core'; @Component({selector : 'app-root',template: `<select (input)="setTheme($event.target.value)" title="theme" class="form-control"><option value="">- select theme -</option><option>green</option><option>pink</option></select><app-trex [dtTheme]="selectedTheme"></app-trex>`,styleUrls : [ './app.component.less' ] }) export class AppComponent {readonly themes = {'green': {'color-main' : '#3D9D46','color-main-darken' : '#338942','color-main-darken2': '#286736','color-main-lighten': '#7BBC4D','color-accent' : '#DC3C2A'},'pink' : {'color-main' : '#E05389','color-main-darken' : '#CA3E86','color-main-darken2': '#C13480','color-main-lighten': '#E77A96','color-accent' : '#208FBC'}};selectedTheme = {};setTheme(val) {this.selectedTheme = this.themes[val];} }

    3.創建一個trex.component.ts組件

    import { Component, OnInit, ViewEncapsulation } from '@angular/core';@Component({selector: 'dt-trex',template: `<div class="class1">aaaa</div><div class="class2">bbb</div><div class="class3">ccc</div><div class="class4">ddd</div>`,styles:`.class1{color:var(--color-main, #ff0000);}.class2{color:var(--color-main-darken);}.class3{color:var(--color-main-darken2);}.class4{color:var(--color-main-lighten);}` }) export class TrexComponent {constructor() { } }

    CSS 定制主題完成了,筆者準備好了源代碼,方便大家查看,點擊查看源碼

    但是這種方式有個缺點,瀏覽器最好支持 CSS3 Variable,如果不支持 CSS3 Variable,那么我還是建議你使用 less 變量。如果你并不想采用 less 的 modifyVars 方式,或者不想重寫 webpack,那么以下這種方式也許適合你。

    3. Angular Configuration

    Angular 的組件默認工作在 ViewEncapsulation.Emulated 模式下,在這個模式下,應用程序的dom元素都會附加額外的屬性,而 index.html 被添加的 style 會包含這些屬性,從而做到組件樣式的隔離;但是 component 中的樣式,打包后最后會以 JS 形式出現(原理可查看上面 “webpack 打包原理”)。

    因此如果想實現主題定制,實際上是需要打多個 angular 的生成包,不過值得高興的是 angular-cli 原生支持同時生成多個 package,我們可以配置 light 和 dark 變量文件,利用 angular-cli 的 builder 打多個主題包,然后利用路由切換不同的主題。

    • ViewEncapsulation.Emulated(默認)樣式將被包裝到 style 標簽中,推送到 head 標簽,并唯一標識,以便與組件的模板匹配,樣式將僅用于同一組件中的模板。
    • ViewEncapsulation.ShadowDom 全局樣式都不會影響后代組件
    • ViewEncapsulation.Native 已棄用
    • ViewEncapsulation.None 樣式包裹在 style 標簽中并推送到 head,緊跟在組件內聯和外部樣式之后,屬于全局樣式。

    下面簡單介紹一下這種方式的實現流程:

  • 配置全局樣式 style.less
  • 注意:customize_theme 是文件夾名稱,存放于 src/product-configurations/styles/(light|dark)下,利用 angular.json 中的 stylePreprocessorOptions(允許添加額外的基準路徑,這些基準路徑將被檢查予以導入,Import ‘customize_theme’,可以成功導入,再也不用寫很長的../../相對路徑)

    @import 'customize_theme';

    2. 配置 angular.json

    注意:升級到 angular8.0 后,configurations 中的 key(如 ligth-theme)不能包含“:”(踩坑),原因這里查看

    "configurations": {"light-theme": {"stylePreprocessorOptions": {"includePaths": ["src/styles","src/product-configurations/styles/light"]}},"dark-theme": {"stylePreprocessorOptions": {"includePaths": ["src/styles","src/product-configurations/styles/dark"]}}... }

    3. 配置 packge.json

    {"name": "app","version": "0.0.1","scripts": {"build:light": "ng build --project=app-build --configuration=light-theme","build:dark": "ng build --project=app-build --configuration=dark-theme"}... }

    這種方式缺點很明顯,需要打包后切換不同語言包,打包時間翻倍,且需要路由來控制語言切換,每次切換語言都要重新加載,性能上比較浪費。既然如此,如何避免這些缺陷了?下面來介紹一種既簡單又性能好的方式。

    4. :host-context()

    :host-context() 是 webComponents 下的 selector,很多人可能都沒有使用過,但是卻是相對而言最適合的主題切換方式。注意 :host-context() 支持的瀏覽器可以在 這里 查看

    :host-context(.theme-light) h2{// 基于當前組件向上查找 .theme-light,有則應用到組件的 h2 中 }

    下面來介紹一下實現這種主題定制的流程:點擊查看源碼

  • 配置 angular.json,暴露兩個主題文件
  • "styles": [ "src/light.less","src/dark.less" ]

    2. 修改 dark.less 和 light.less 文件

    @html-selector: html; @primary-color: blue; @html-selector: html; @primary-color: red;

    3. 配置全局樣式 styles.less 文件

    .themeMixin(@rules) {:host-context(.dark) {@import "theme-dark";@rules();}:host-context(.light) {@import "theme-light";@rules();} }

    4. 配置 app.component.less 應用

    @import "../styles"; .themeMixin({p {color: @primary-color;} });

    5. 在瀏覽器中給 body 添加 class='dark|light',即可看到效果。

    以上方式可以實現 less 的主題動態切換,無需打包和設置路由,但是 :host-context() 和 :host 混用,會有些問題,具體可查看這里。

    其他組件中有主題概念,需要用 themeMixin 包起來使用,此外 @html-selector 變量可以實現兩種主題共同存在,如果你需要的話。

    對比以上四種方式

    • webpack loader:瀏覽器都支持,需多次打包,支持:host混用,流程比較復雜;
    • CSS Variable:Chrome 49以上、FireFox 31以上、Safari 9.1以上、IE不支持,1次打包,支持:host混用,流程簡單直接
    • Angular Configuration:瀏覽器都支持,需多次打包,支持:host混用,流程簡單直接
    • :host-context():Chrome 54以上、opera 41以上,FireFox 、Safari、IE不支持,1次打包 ,不支持:host混用,流程比較復雜

    總結

    以上是生活随笔為你收集整理的angular cli 切换 css_漫谈 Angular 定制主题的四种方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。