You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ExtJS 6.6 Classic Toolkit中实现主题切换器(明暗模式)

ExtJS 6.6 Classic Toolkit 主题切换实现方案

针对ExtJS 6.6 Classic的主题切换需求,以下是两种经过验证的可行方案,覆盖明暗模式切换和多主题切换场景:


方案一:动态替换主题CSS文件(支持多主题切换)

这种方法适合需要在多个完整主题(如Triton、Neptune、Triton暗色)之间切换的场景,核心是预编译所有主题的CSS文件,运行时动态替换页面中的CSS链接。

步骤1:预编译主题CSS

使用Sencha Cmd为每个需要切换的主题编译完整的CSS文件:

  1. 在项目根目录执行命令,编译指定主题:
    sencha app build --theme triton
    sencha app build --theme triton-dark
    sencha app build --theme neptune
    
  2. 编译完成后,将生成的theme-[主题名]-all.css文件复制到项目的resources/css目录下统一管理。

步骤2:实现主题切换工具类

创建单例工具类处理CSS的加载与替换:

Ext.define('App.util.ThemeSwitcher', {
    singleton: true,
    currentTheme: 'triton', // 默认主题

    switchTheme: function(themeName) {
        // 移除当前主题的CSS链接
        const currentLink = Ext.dom.Query.select(`link[data-theme="${this.currentTheme}"]`)[0];
        if (currentLink) {
            currentLink.parentNode.removeChild(currentLink);
        }

        // 加载新主题CSS(添加时间戳避免缓存)
        const themePath = `resources/css/theme-${themeName}-all.css?_dc=${new Date().getTime()}`;
        const newLink = document.createElement('link');
        newLink.rel = 'stylesheet';
        newLink.href = themePath;
        newLink.setAttribute('data-theme', themeName);

        document.head.appendChild(newLink);

        // 更新当前主题记录并持久化到本地存储
        this.currentTheme = themeName;
        localStorage.setItem('app-selected-theme', themeName);

        // 刷新所有组件样式
        Ext.ComponentQuery.query('*').forEach(comp => {
            if (comp.rendered) {
                comp.updateLayout();
                typeof comp.refresh === 'function' && comp.refresh();
            }
        });
    },

    // 页面加载时恢复用户上次选择的主题
    init: function() {
        const savedTheme = localStorage.getItem('app-selected-theme') || this.currentTheme;
        this.switchTheme(savedTheme);
    }
});

// 页面初始化时调用
Ext.onReady(() => {
    App.util.ThemeSwitcher.init();
});

步骤3:添加切换控件(下拉框/按钮)

以下拉框为例,实现主题选择界面:

Ext.create('Ext.form.ComboBox', {
    fieldLabel: '选择主题',
    store: Ext.create('Ext.data.Store', {
        fields: ['name', 'text'],
        data: [
            { name: 'triton', text: 'Triton 亮色' },
            { name: 'triton-dark', text: 'Triton 暗色' },
            { name: 'neptune', text: 'Neptune' }
        ]
    }),
    valueField: 'name',
    displayField: 'text',
    value: App.util.ThemeSwitcher.currentTheme,
    listeners: {
        select: function(combo, record) {
            App.util.ThemeSwitcher.switchTheme(record.get('name'));
        }
    },
    renderTo: Ext.getBody()
});

方案二:CSS类切换(适合快速明暗模式切换)

如果仅需明暗模式切换,无需加载完整主题CSS,可以通过给body添加/移除类名的方式实现,编译主题时提前生成两种模式的样式规则。

步骤1:修改主题SASS变量

在当前主题的sass/var目录下(如triton/sass/var/Component.scss),通过body类名区分明暗模式变量:

// 默认亮色模式
$base-color: #f5f5f5;
$text-color: #333;
$border-color: #ddd;

// 暗色模式
body.dark-mode {
    $base-color: #1a1a1a;
    $text-color: #ffffff;
    $border-color: #444;

    // 覆盖其他组件的变量,如网格表头、按钮样式等
    $grid-header-background-color: darken($base-color, 10%);
    $button-base-color: darken($base-color, 15%);
}

步骤2:编译主题并实现切换逻辑

编译主题后,通过简单的类名切换即可完成明暗模式切换:

function toggleDarkMode() {
    const body = document.body;
    const isDark = body.classList.toggle('dark-mode');
    
    // 持久化设置
    localStorage.setItem('app-dark-mode', isDark);
    
    // 刷新组件布局
    Ext.ComponentQuery.query('*').forEach(comp => {
        comp.rendered && comp.updateLayout();
    });
}

// 页面初始化时恢复设置
Ext.onReady(() => {
    const isDark = localStorage.getItem('app-dark-mode') === 'true';
    if (isDark) {
        document.body.classList.add('dark-mode');
    }
});

// 添加切换按钮
Ext.create('Ext.button.Button', {
    text: '切换明暗模式',
    handler: toggleDarkMode,
    renderTo: Ext.getBody()
});

关键注意事项

  1. 主题编译必须用Sencha Cmd:ExtJS主题依赖大量SASS变量和混合宏,未编译的SASS文件无法直接在浏览器中使用。
  2. 组件样式刷新:部分复杂组件(如网格、树形控件)切换主题后需要手动调用updateLayout()或refresh()更新样式。
  3. 缓存处理:动态加载CSS时添加_dc参数,避免浏览器缓存旧的主题文件。

内容的提问来源于stack exchange,提问作者tamtejszystan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:22:32