在Typescript中访问SASS值(来自variables.scss的$ colors)(Angular2 ionic2)

nyl*_*uje 41 sass typescript ionic2 angular

在Ionic 2中,我想$colors从文件"[my project]\src\theme\variables.scss"中访问变量.

该文件包含:

$colors: (
  primary:    #387ef5,
  secondary:  #32db64,
  danger:     #f53d3d,
  light:      #f4f4f4,
  dark:       #222,
  favorite:   #69BB7B
);
Run Code Online (Sandbox Code Playgroud)

在一个组件中,我画一个画布.它看起来像这样:

import {Component, Input, ViewChild, ElementRef} from '@angular/core';

@Component({
    selector: 'my-graph',
})
@View({
    template: `<canvas #myGraph class='myGraph'
     [attr.width]='_size'
     [attr.height]='_size'></canvas>`,
})

export class MyGraphDiagram {
    private _size: number;

    // get the element with the #myGraph on it
    @ViewChild("myGraph") myGraph: ElementRef; 

    constructor(){
        this._size = 150;
    }

    ngAfterViewInit() { // wait for the view to init before using the element

      let context: CanvasRenderingContext2D = this.myGraph.nativeElement.getContext("2d");
      // HERE THE COLOR IS DEFINED AND I D LIKE TO ACCESS variable.scss TO DO THAT
      context.fillStyle = 'blue';
      context.fillRect(10, 10, 150, 150);
    }

}
Run Code Online (Sandbox Code Playgroud)

可以看出,在这段代码中的某个时刻,形状的颜色被定义为: context.fillStyle = 'blue',我想使用类似的东西context.fillStyle = '[variables.scss OBJECT].$colors.primary '.

有人有想法吗?

Met*_*mur 38

不幸的是,没有办法直接从typescript/javascript代码访问SASS变量.但是,我们可以制定解决方法来访问这些变量.

让我简要介绍一下从typescript源代码中访问SASS变量的步骤:

1.创建SASS助手组件

创建../providers/sass-helper/sass-helper.component.scss:

$prefix: "--"; //Prefix string for custom CSS properties

//Merges a variable name with $prefix
@function custom-property-name($name) {
    @return $prefix + $name;
}

// Defines a custom property
@mixin define-custom-property($name, $value) {
    #{custom-property-name($name)}: $value;
}

body {
    // Append pre-defined colors in $colors:
    @each $name, $value in $colors {
        @include define-custom-property($name, $value);
    }

    // Append SASS variables which are desired to be accesible:
    @include define-custom-property('background-color', $background-color);
}
Run Code Online (Sandbox Code Playgroud)

在这个SCSS文件中,我们只是在DOM 的body部分内创建自定义属性.您应该使用调用的mixin将要访问的每个SASS变量添加到此SCSS文件中,该调用define-custom-property需要两个参数:变量名和变量值.

作为一个例子,我已经添加条目的所有颜色中定义$colors以及对SASS变量的条目$background-color在我的定义主题/ variables.scss文件.您可以根据需要添加任意数量的变量.

创建../providers/sass-helper/sass-helper.component.ts:

import { Component } from '@angular/core';

export const PREFIX = '--';

@Component({
    selector: 'sass-helper',
    template: '<div></div>'
})
export class SassHelperComponent {

    constructor() {

    }

    // Read the custom property of body section with given name:
    readProperty(name: string): string {
        let bodyStyles = window.getComputedStyle(document.body);
        return bodyStyles.getPropertyValue(PREFIX + name);
    }
}
Run Code Online (Sandbox Code Playgroud)

2.集成SASS Helper组件

从现在开始,我们可以遵循标准的Ionic2框架原则来进行组件集成和使用.

  • 将组件类名称(SassHelperComponent)添加到app.module.tsNgModule的声明部分
  • 将以下HTML代码插入到您要访问这些魔术变量的页面的HTML模板中:

    <sass-helper></sass-helper>


3.使用帮助程序组件

在页面的TS文件中,您应该在页面类中插入以下行:

@ViewChild(SassHelperComponent)
private sassHelper: SassHelperComponent;
Run Code Online (Sandbox Code Playgroud)

最后,您可以通过调用子类方法来读取任何SASS变量的值,如下所示:

// Read $background-color:
this.sassHelper.readProperty('background-color');

// Read primary:
this.sassHelper.readProperty('primary');
Run Code Online (Sandbox Code Playgroud)

  • 是的,但必须有一个更简单的方法. (6认同)

yuv*_*uva 8

我想在@mete-cantimur 的回答中添加一些内容。

import {Component, OnInit, ViewEncapsulation} from '@angular/core';

const PREFIX = '--';

@Component({
  selector: 'app-styles-helper',
  templateUrl: './styles-helper.component.html',
  styleUrls: ['./styles-helper.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class StylesHelperComponent implements OnInit {

  ngOnInit(): void {

  }

  readProperty(name: string): string {
    const bodyStyles = window.getComputedStyle(document.body);
    return bodyStyles.getPropertyValue(PREFIX + name);
  }
}
Run Code Online (Sandbox Code Playgroud)

我的辅助组件无法修改主体样式。即使我正确设置了所有内容,自定义属性也没有被保存。

我必须添加encapsulation: ViewEncapsulation.None到组件才能让它修改主体样式。

希望这可以帮助。


ber*_*ing 5

一种可能性是产生一个.ts从文件.scss的文件。此过程的一个简单示例:

1)安装npm i --save-dev scss-to-json

2)放入您的package.json

  "scripts": {
    ...
    "scss2json": "echo \"export const SCSS_VARS = \" > src/app/scss-variables.generated.ts && scss-to-json src/variables.scss >> src/app/scss-variables.generated.ts"
  },
Run Code Online (Sandbox Code Playgroud)

并使用运行它npm run scss2json。Windows用户将需要调整示例。

3)访问变量:

import {SCSS_VARS} from './scss-variables.generated';
...
console.log(SCSS_VARS['$color-primary-1']);
Run Code Online (Sandbox Code Playgroud)

这样的一个优点是,您将获得IDE的类型完成功能,这是通常实现目标的一种非常简单的方法。

当然,您可以使此功能更高级,例如,将生成的文件设置为只读,并将脚本放入其自己的.js文件中,并使其可在每个OS上使用。


tia*_*ves 5

这可以使用 CSS 模块实现。

CSS 模块

从项目描述

当从 JS 模块导入 CSS 模块时,它会导出一个对象,其中包含从本地名称到全局名称的所有映射。

我们可以像这样从 css/scss 文件中读取变量:

import styles from "./style.css";    

element.innerHTML = '<div class="' + styles.className + '">';
Run Code Online (Sandbox Code Playgroud)

默认情况下,Angular CLI 已经设置了对 CSS 模块的支持,该 CLI 使用配置了css-loader 的Webpack 。

使其工作的步骤是:

  1. 仅导出要使用的 scss 变量。
  2. styles.scss.
  3. 在打字稿组件中导入变量。

1 - 导出变量

在您的 中styles.scss,使用关键字:export导出 $colors。好像:export不支持导出maps,只支持字符串,所以我们必须创建一个mixin来将map转换为字符串:

$colors: (
  primary: #387ef5,
  secondary: #32db64,
  danger: #f53d3d,
  light: #f4f4f4,
  dark: #222,
  favorite: #69bb7b,
);

@mixin rule($key, $value, $prefix) {
  #{$prefix}-#{$key}: $value;
}
@mixin map-to-string($map, $prefix) {
  @each $key, $value in $map {
    @include rule($key, $value, $prefix);
  }
}

:export {  
  @include map-to-string($colors, "colors");
}
Run Code Online (Sandbox Code Playgroud)

生成的:export将是:

:export {
  "colors-danger": "#f53d3d";
  "colors-dark": "#222";
  "colors-favorite": "#69bb7b";
  "colors-light": "#f4f4f4";
  "colors-primary": "#387ef5";
  "colors-secondary": "#32db64";
}
Run Code Online (Sandbox Code Playgroud)

2 - 配置一个打字稿模块 styles.scss

我们必须创建一个styles.scss.d.ts包含以下内容的文件以允许styles.scss在我们的打字稿文件中导入:

export interface globalScss {}

export const styles: globalScss;

export default styles;
Run Code Online (Sandbox Code Playgroud)

3 - 在目标打字稿组件中导入变量

当我们使用默认导出时,我们可以像这样将它导入到我们的组件中:

//...
import styles from 'src/styles.scss';

@Component({
  selector: 'app-colors-use',
  templateUrl: './colors-user.component.html',
  styleUrls: ['./colors-user.component.scss'],
})
export class ColorsUserComponent implements OnInit {

  buttonColor = styles["colors-primary"] //"#387ef5"
Run Code Online (Sandbox Code Playgroud)

4 -(加号)将类型定义添加到 styles.scss.d.ts

您可以将类型信息添加到style.scss.d.ts

export interface globalScss {  
  "colors-danger": string
  "colors-dark": string
  "colors-favorite": string
  "colors-light": string
  /**
   * Used for app-button, usually blue
   */
  "colors-primary": string
  /**
   * Used for borders, usually green
   */
  "colors-secondary": string
}

export const styles: globalScss;

export default styles;
Run Code Online (Sandbox Code Playgroud)

这样,你可以在像 VS 代码这样的编辑器中获得一些好处:

注释

自动完成

更新:

上面的配置只适用于 ng 10。Css Modules 配置从 ng 10 到 ng 11 发生了很大变化。