可切换Vaadin 12主题的最佳实践

可切换Vaadin 12主题的最佳实践,vaadin,vaadin-flow,vaadin12,vaadin-themes,Vaadin,Vaadin Flow,Vaadin12,Vaadin Themes,我目前正在将Vaadin 8应用程序迁移到Vaadin 12。用户应使用外观,并在登录时或通过按下按钮进行更改 在我们的vaadin8应用程序中,我们有两个主题(一个暗主题和一个亮主题),每个主题都有自己的SASS/CSS和一些共享属性。用户可以使用setTheme()方法进行切换。当点击切换按钮时,外观和感觉发生了变化。在Vaadin 12中,主题化采用了不同的方法,我正在努力寻找一种在Vaadin 12中实现此功能的好方法 假设我们不想创建一个全新的主题,只想使用定制的LUMO。我可以通过@

我目前正在将Vaadin 8应用程序迁移到Vaadin 12。用户应使用外观,并在登录时或通过按下按钮进行更改

在我们的vaadin8应用程序中,我们有两个主题(一个暗主题和一个亮主题),每个主题都有自己的SASS/CSS和一些共享属性。用户可以使用setTheme()方法进行切换。当点击切换按钮时,外观和感觉发生了变化。在Vaadin 12中,主题化采用了不同的方法,我正在努力寻找一种在Vaadin 12中实现此功能的好方法

假设我们不想创建一个全新的主题,只想使用定制的LUMO。我可以通过@Theme注释设置主题/变体。缺点:主题将在运行时修复

此外,我还可以编写一些代码,将变体应用于我的应用程序和组件。(如“动态样式”一章中所述:) 缺点:迭代每个元素并应用变量是不太可行的

我现在的问题是:

在运行时实现主题切换的最佳方法是什么?(Lumo或任何其他主题的自定义明暗变体)

我会创建两个包含CSS的HTML文件(为了兼容性),然后通过动态导入覆盖当前使用的文件吗


我希望我的问题很清楚,有人能给我指出正确的方向。

在同一主题的两个不同变体之间切换相对容易,例如Lumo的黑暗变体和光明变体。为此,只需在
元素上切换相应的
主题
属性。服务器无法直接访问该元素,但您可以使用一小段JavaScript来实现:
ui.getPage().executeJavaScript(“document.documentElement.setAttribute($0,$1)”,“theme”,“dark”)

根据具体情况,您可以或必须将更改应用于
元素。在这种情况下,您可以在JS代码段中为
.body
切换出
.documentElement
,也可以在Java中直接使用
ui.getElement().setAttribute(“主题”、“黑色”)


在两个不同的基本主题之间切换,例如Lumo vs Material是一件复杂得多的事情。对于每个组件,同一时间只能在浏览器中加载一个基本主题,而重新加载页面是摆脱已加载主题的唯一方法。对于用于流的每个组件,框架除了负责加载没有任何样式的基本导入外,还负责加载正确的主题导入。为了使事情更加复杂,使用
@theme
指定的主题会自动包含在应用程序的生产包中。为了能够使用多个基本主题,您还必须以某种方式生成多个不同的bundle,并根据情况以某种方式配置Flow以使用正确的bundle。

如果您只想在明暗之间切换,那么您只需在DOM中非常高的位置添加/删除
。例如,UI的元素通常是
主体
,或者至少是非常高的层次

例如:

编辑

正如另一个答复的评论中所问:

要更改主题中的颜色,可以替代使用的颜色。以下是如何更改亮和暗Lumo主题的文本颜色的示例:

html{
--lumo正文颜色:红色;
}
[主题~=“黑暗”]{
--lumo正文颜色:黄色;
}

非常感谢您。假设我现在要自定义外观。如果我只是使用主题的一个变体(比如说浅色版本),并且我想要有一个不同的字体颜色或背景颜色,我只需要创建一个HTML/CSS文件并覆盖它。但假设我想改变这两种变体的外观:在“浅”中使用红色字体颜色,在“暗”中使用绿色字体颜色(仅作为示例)。我该怎么办?我需要两个CSS文件并切换它们吗?或者,是否有一种方法仅在使用特定变体时应用样式?这是我最不清楚的一点。用一句话来说:定制Lumo的明暗变体最可行的方法是什么?@Loahrs我已经在我的答案中添加了这一点。然而,与其把它放在评论中,不如在另一个问题中问这个问题?太好了,这正是我想要的!谢谢在vaadin文档中找不到这些信息,但我确信必须有这样的符号才能使之成为可能,而不会有太多麻烦。仅供参考,在vaadin 14中,使用现代web浏览器和四行JavaScript,您的web应用程序可以动态地在亮模式和暗模式之间切换,以匹配用户在主机操作系统中设置的首选项。请参见问题。另请参见Marcus Hellberg在Vaadin.com上的帖子。
new Checkbox("Use Dark Theme").tap{
    addValueChangeListener{ cb ->
        getUI().ifPresent(){ ui ->
            def themeList = ui.getElement().getThemeList()
            if (cb.value) {
                themeList.add(Lumo.DARK)
            } else {
                themeList.remove(Lumo.DARK)
            }
        }
    }
}