如何使用LESS

时间:2019-01-25 20:34:40

标签: javascript css vue.js webpack less

我正在使用vue和webpack编写单个文件组件,并使用less-loader来解析组件文件中的<style lang="less"></style>字段

我正在寻找一种能够为网站编写主题的好方法。理想情况下,我想像这样拥有单独的theme.less文件:

src
|--themes
|  |-- light.less
|  |-- dark.less
|--components
   |-- app.vue
   |-- nav.vue

theme.less文件由通用变量组成的地方:

@bg:      hsl(251, 44%, 95%);
@sub:     hsl(251, 18%, 81%);
@surface: hsl(251, 18%, 81%);
@text:    hsl(0, 0%, 0%);
@link:    ...

这样我就可以以主题无关的方式编写组件级样式:

<style lang="less">
    #main-content {
        background-color: @bg;
        color: @text;
        border: @primary;
    }
</style>

并生成将我提供的样式包装在主题类中的css:

.light #main-content {
    background-color: [@bg variable in light.less];
    color: [@text variable in light.less];
    border: [@primary variable in light.less];
}

.dark #main-content {
    background-color: [@bg variable in dark.less];
    color: [@text variable in dark.less];
    border: [@primary variable in dark.less];
}

这样我就可以将主题类应用于<body class="dark">之类的根元素并显示适当的样式。

最好的方法是什么?



当前,我已经实现了自己的解决方案,该解决方案使用了inject提供的style-resources-loader功能:

module.exports = function (source, resources) {
    let newSource = source.trim();

    let themes = resources.map(v => {
        let o = {};
        o.default = v.content.startsWith("/**DEFAULT**/");
        o.name = v.file.split('/').pop().replace(/\.[^/.]+$/, "");
        return o;
    });

    let wrappers = themes.map(v => `
${v.default ? 'body' : '.' + v.name} {
    @import (reference) '../themes/${v.name}.less';
`);

    let compiled = "";
    wrappers.forEach(w => {
        compiled += w + newSource + '\n}\n';
    })

    return compiled
}

这是针对每个组件的style代码的,它会创建多个主题类块,例如

.light { 
    @import (reference) '../themes/light.less';
    [injected source code]
}

.dark { 
    @import (reference) '../themes/dark.less';
    [injected source code]
}

并在导入后插入样式代码,从而允许将组件中的@variable引用的范围限定为主题,并输出包含包装在多个主题类中的所有样式的css(因此复制了我为之编写的所有样式我可以使用的每个主题)

我主要是问是否有更好的方法可以实现此目的,可能是通过webpack,vue或一些我所忽略的内置功能实现的。

谢谢!

1 个答案:

答案 0 :(得分:0)

我有完全相同的需求。但是,我选择了另一种使用CSS Custom Properties(又称CSS变量)的方法。

重构您的LESS变量,例如:

@bg:      var(--bg, lime);
@sub:     var(--sub, lime);
@surface: var(--surface, lime);
@text:    var(--text, lime);
@link:    ...

然后为每个主题定义CSS变量:

:root {
  --bg:      hsl(251, 44%, 95%);
  --sub:     hsl(251, 18%, 81%);
  --surface: hsl(251, 18%, 81%);
  --text:    hsl(0, 0%, 0%);
  --link:    ...
}

基本上,这就是您需要的一切。它工作得很好,甚至具有额外的好处,我什至可以使用开发工具直接在浏览器中播放颜色,或者将它们添加为用户设置,以允许用户定义自己的主题。