UnoCSS 确实简化了不少样式书写、也降低了 CSS 打包体积,提升了样式使用率。但样式太多的话,class 也写得多,比较费眼。所幸,UnoCSS 提供了 shortcuts 来简化 class,并且可以通过 js 来控制样式的输出,灵活度非常高。

shortcuts 与 rules 不同的是,rules 只可以写 CSS 属性/值,shortcuts 是提高 rules 的利用率,且降低写太多重复的 class。

shortcuts 有动态和静态,我推荐多用动态的。我就直接丢上官方文档给出的静态 shortcuts 例子:

shortcuts: {
  // shortcuts to multiple utilities
  'btn': 'py-2 px-4 font-semibold rounded-lg shadow-md',
  'btn-green': 'text-white bg-green-500 hover:bg-green-700',
  // single utility alias
  'red': 'text-red-100'
}

下面是我写的动态 shortcuts,目的是简化 flex、items-xxx、content-xxx、justify-xxx 的使用:

const shortcuts = <UserShortcuts>[
  [
    /^f-((c|s|e)(-(c|s|e|b))*)$/,
    ([, group1, group2, group3, group4]) => {
      const matches = [
        { prefix: "c", value: "center" },
        { prefix: "s", value: "start" },
        { prefix: "e", value: "end" },
        { prefix: "b", value: "between" }
      ];

      if (group4) {
        let style = ``;

        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group2) {
            style += `flex items-${matches[i].value} content-${matches[i].value}`;
          }
        }

        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group4) {
            style += ` justify-${matches[i].value}`;
          }
        }

        return style;
      } else {
        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group2) {
            return `flex items-${matches[i].value} content-${matches[i].value}`;
          }
        }
      }
    }
  ]
];

代码没有做优化。动态 shortcuts 包含多个数组元素,元素包含两个子元素。第一个元素是正则表达式;第二个是正则表达式匹配的结果。正则表达式匹配至少一个组,比如我写的正则表达式可视化图:

image

这个正则表达式匹配了四个组,而我需要的是 组2 和 组4。所以,我不需要([, group1, group2, group3, group4]) => { return "" }总的 group1、group3,而是 group2 和 group4 匹配的值,动态设置 rules。下面是使用案例,在 class 中写 f-c-s 就可以用上 flex 相关的样式:

image

并且支持匹配 f-c,该 shortcuts 不使用 justify-content 样式:

image

总结:shortcuts 获取匹配的值与正则表达式匹配的组有关系,一一对应的关系。