如何在 SCSS 中使用 @function 反转变量顺序

问题描述 投票:0回答:1

好的,所以我正在开发一个自定义的 scss 框架,并且我试图使所有预定义的变量都可以由用户轻松配置,但是由于 css 的工作方式,我需要在某些配置中反转某个变量,以便它们以正确的方式相互覆盖。现在我的变量配置如下:

$order-direction: 'ascending' !default;
$order: null !default;

$1: '1' !default;
$2: '2' !default;
$3: '3' !default;

@if $order-direction == 'ascending' {
     $order:(
          "1":$1,
          "2":$2,
          "3":$3
     );
}
@if $order-direction != 'ascending' {
     $order:(
          "3":$3,
          "2":$2,
          "1":$1
     );
}

这可行,但它使得我无法更改变量的名称(我稍后会在我的 css 类名中引用它),并且也使得我无法在之后添加更多内容。我想做的是使用一个变量,如果我改变顺序方向,该变量就会反转,如下所示:

$order-direction: 'ascending' !default;
$order: null !default;

$numbers:(
     "1":1,
     "2":2,
     "3":3
) !default;

@function reverse($v){
     $r: null;
     @for 1 through length($numbers){
          something that makes $r = reverse of $v
     };
     @return $r
};

@if $order-direction == 'ascending' {
     $order: $numbers;
};
@if $order-direction != 'ascending' {
     $order: reverse($numbers);
};

如果我能让这个工作,我可以让用户重新定义 $numbers 和 $order-direction 变量来设置所有相应的逻辑,而不是每个 $1、$2...等以及 $order-direction单独变量。此更改允许我使用标准的 @each $key, $value{} 运算符来创建类名称,用户可以更改派生类的名称和数量。

但是,我不知道如何根据数字从 sass 变量中提取某些内容,就像在 .js 中那样(类似于numbers[i])。我知道你可以使用 sass map 在对象中查找某些内容,例如 .js 字典查找,但我想不出一种方法可以像在 sass 中那样工作。

想法?

(P.S.我可能在某个地方漏掉了分号或逗号,我完全清楚,但我用不同的名称重新输入了这个,以便让它更有意义)

就像我说的,我的代码当前正在运行,但用户无法扩展。我试图找到一种使用 @map 的方法,但为了实现这一点,我需要保持名称相同,并且用户仍然无法向 $numbers 添加更多内容以供我的 sass 评估。

css sass node-sass scss-mixins
1个回答
0
投票

好吧,我做了很多挖掘,找到了一种方法来做到这一点,但这需要几个步骤。首先让我们看一下我发布的示例:

$order-direction: 'ascending' !default;
$order: null !default;

$numbers:(
     "1":1,
     "2":2,
     "3":3
) !default;

@function reverse($v){
     $r: null;
     @for 1 through length($numbers){
          something that makes $r = reverse of $v
     };
     @return $r
};

@if $order-direction == 'ascending' {
     $order: $numbers;
};
@if $order-direction != 'ascending' {
     $order: reverse($numbers);
};

我们保持定义的变量不变,然后函数需要执行几个步骤。首先,我们获取变量映射并将其转换为 2 个列表,一个用于名称,一个用于值:

@function reverse($val){

$names: null;
$values: null;

@each $n, $v in $val{
    $names: append($names, $n);
    $values: append($values, $v);
};

....

现在我们有一组 2 个原始列表,一个包含名称,另一个包含值。将变量分配给它们自己也很重要,因为 sass 不会使用append()动态更新变量。现在我们必须再次将它们重新组合成地图,我们这样做:

@for $i from 1 through length($names){
$r: map.set( $r, list.nth($names, ($i * -1) ), list.nth($values, ($i * -1) ));
};
        
@return $r;
};

完成此操作后,我们将从最后一个到第一个的列表组合成一个新的映射变量。由于我们同时使用了地图和列表,因此我们还需要适当的@use,因此我们将这两者都包含在内,然后我们得到:

@use "sass:map";
@use 'sass:list';

$order-direction: 'ascending' !default;
$order: null !default;

$numbers:(
     "1":1,
     "2":2,
     "3":3
) !default;

@function reverse($val){

    $names: null;
    $values: null;

    @each $n, $v in $val{
        $names: append($names, $n);
        $values: append($values, $v);
    };
    @for $i from 1 through length($names){
        $r: map.set( $r, list.nth($names, ($i * -1) ), list.nth($values, ($i * -1) ));
    };
        
    @return $r;
};

@if $order-direction == 'ascending' {
     $order: $numbers;
};
@if $order-direction != 'ascending' {
     $order: reverse($numbers);
};

使用此配置,当变量 $order 设置为“升序”时,我们会得到一个 $numbers 变量,其值为 1,2,3,当它不是“升序”时,我们会得到 3,2,1。这对于在 css 中安排覆盖非常有用,因为应用了 css 中的最新类。对于我的用例,我使用它来更改断点的行为,以使用 min-width 或 max-width 来确定其 @media 规则,并且如果用户想要更改该功能(可能更像引导程序,但向后)可能是)现在就像翻转单个变量一样简单。但我不知道我的答案是否是最有效的。

© www.soinside.com 2019 - 2024. All rights reserved.