【发布时间】:2019-06-19 17:00:48
【问题描述】:
我正在使用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"> 这样的根元素并显示适当的样式。
最好的方法是什么?
目前我已经实现了自己的解决方案,它使用了style-resources-loader 提供的inject 功能:
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 或我忽略的一些内置功能。
谢谢!
【问题讨论】:
标签: javascript css vue.js webpack less