gpt4 book ai didi

javascript - 如何使用 LESS 在 vue/webpack 中创建主题

转载 作者:搜寻专家 更新时间:2023-10-30 22:50:06 25 4
gpt4 key购买 nike

我正在使用 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 所做的代码,它创建多个主题类 block ,如

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

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

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

我主要是问是否有更好的方法来实现这一点,可能是通过 webpack、vue 或我忽略的更少的内置功能。<​​/p>

谢谢!

最佳答案

我有完全相同的需求。然而,我选择了另一种使用 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: ...
}

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

关于javascript - 如何使用 LESS 在 vue/webpack 中创建主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54372400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com