# mixin函数优化[.px2rem()]

作者: 东润

# 优化原因

现阶段移动端组件及项目中直接使用了.px2rem()mixin函数来将px转换rem,即:

@baseFontSize: 75px;

.px2rem(@name, @px)  {
  @{name}: @px / @baseFontSize * 1rem;
}

但是在重构移动端组件库过程中,发现该mixin函数对以下两种情况都无法兼容

.a {
  .px2rem(width, 100%);
  .px2rem(margin, 10px 20px);
}

需要通过直接写或者拆开来写实现

  .a {
    width:100%;
    .px2rem(margin-top, 10px);
    .px2rem(margin-left, 20px);
    .px2rem(margin-bottom, 10px);
    .px2rem(margin-right, 20px);
  }

# 解决方案

为了解决以上问题,对.px2rem()进行了以下的优化

  1. 通过对应 @px参数的数量进行判断,重载出一个@px为多参数的.px2rem()mixin函数。

  2. @px进行判断,判断是否是数字及非百分比数字。

  3. 多参数的.px2rem()mixin函数,通过each去获取多参数@px的每一个参数,以便于对每个参数做处理。

  4. 通过对@{name}增加+标识,表示对属性值进行拼接,_标识通过空格拼接,即@{name}+_

完整代码如下:

@baseFontSize: 75px;

.px2rem(@name, @px) when (length(@px)=1) {
  @computable: boolean((isnumber(@px)) and (not(ispercentage(@px))));
  @{name}: if(@computable, (if(@computable, @px, 0) / @baseFontSize * 1rem), @px);
}

// 适用于 margin: 0 auto; 等多值情况
.px2rem(@name, @px) when (length(@px) > 1) {
  each(@px, {
      @computable: boolean((isnumber(@value)) and (not(ispercentage(@value))));
      @{name}+_:if(@computable, (if(@computable, @value, 0) / @baseFontSize * 1rem), @value);
    }
  )
}

# 如何使用

通过引用 @h3/theme-mobile 依赖,引用以下代码即可使用

@import '~@h3/theme-mobile/core/mixins/index.less';

# 展望

直接使用了.px2rem()弊端是在写UI样式时比较繁琐,且无法灵活的转变更好的替换方案viewport

未来某个时间段将弃用该方式,直接写px单位,然后通过postcss插件转换。