Я использую vue с веб-пакетом для записи отдельных файловых компонентов, используя 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 со всеми стилями, обернутыми в несколько классов тем (таким образом, дублируя все стили, которые я пишу для каждой темы) У меня есть в наличии)
В основном я спрашиваю, есть ли лучший способ добиться этого, возможно, с помощью некоторых встроенных функций в веб-пакете, vue или менее, которые я пропустил.
Спасибо!